Skip to content

Commit adec2ed

Browse files
authored
4.2.1 Release
2 parents d312d1f + 25e6125 commit adec2ed

32 files changed

+918
-119
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ before_install:
3333

3434
before_script:
3535
# install deps and UF
36-
- composer install
36+
- COMPOSER_MEMORY_LIMIT=-1 travis_retry composer install --no-interaction
3737
- php bakery debug
3838
- php bakery build-assets
3939
- php bakery migrate

CHANGELOG.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [v4.2.1]
9+
10+
### Added
11+
- `UserFrosting\Sprinkle\Core\Database\Models\Session` model for the `sessions` db table.
12+
- `TEST_SESSION_HANDLER` environment variable to set the session save handler to use for Testing.
13+
- `withDatabaseSessionHandler` Trait for testing. Use `$this->useDatabaseSessionHandler()` to use database session handler in tests.
14+
15+
### Fixed
16+
- Italian translation ([#950])
17+
- User Registration failing when trying to register two accounts with the same email address ([#953])
18+
- Bad test case for `CoreController::getAsset`.
19+
- User Model `forceDelete` doesn't remove the record from the DB ([#951])
20+
- Fix PHP Fatal error that can be thrown when registering a new User
21+
- Session not working with database handler ([#952])
22+
- Remove any persistences when forceDeleting user to prevent Foreign Key Constraints issue ([#963])
23+
- More helpful error message in checkEnvironment.php (Thanks @amosfolz; [#958])
24+
- Hide locale select from UI if only one locale is available (Thanks @avsdev-cw; [#968])
25+
- Download CSV filename error ([#893])
26+
827
## [v4.2.0]
928
### Changed Requirements
1029
- Changed minimum Node.js version to **v10.12.0**
@@ -702,7 +721,16 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
702721
[#869]: https://github.com/userfrosting/UserFrosting/issues/869
703722
[#872]: https://github.com/userfrosting/UserFrosting/issues/872
704723
[#888]: https://github.com/userfrosting/UserFrosting/issues/888
724+
[#893]: https://github.com/userfrosting/UserFrosting/issues/893
705725
[#919]: https://github.com/userfrosting/UserFrosting/issues/919
706726
[#940]: https://github.com/userfrosting/UserFrosting/issues/940
727+
[#950]: https://github.com/userfrosting/UserFrosting/issues/950
728+
[#951]: https://github.com/userfrosting/UserFrosting/issues/951
729+
[#952]: https://github.com/userfrosting/UserFrosting/issues/952
730+
[#953]: https://github.com/userfrosting/UserFrosting/issues/953
731+
[#958]: https://github.com/userfrosting/UserFrosting/issues/958
732+
[#963]: https://github.com/userfrosting/UserFrosting/issues/963
733+
[#968]: https://github.com/userfrosting/UserFrosting/issues/968
707734

708735
[v4.2.0]: https://github.com/userfrosting/UserFrosting/compare/v4.1.22...v4.2.0
736+
[v4.2.1]: https://github.com/userfrosting/UserFrosting/compare/v4.2.0...v4.2.1

app/defines.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace UserFrosting;
1111

1212
// Some standard defines
13-
define('UserFrosting\VERSION', '4.2.0');
13+
define('UserFrosting\VERSION', '4.2.1');
1414
define('UserFrosting\DS', '/');
1515
define('UserFrosting\PHP_MIN_VERSION', '5.6');
1616
define('UserFrosting\PHP_RECOMMENDED_VERSION', '7.1');

app/sprinkles/account/locale/it_IT/messages.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,5 +182,5 @@
182182
'USER_OR_EMAIL_INVALID' => "L'indirizzo mail o il nome utente non sono validi",
183183
'USER_OR_PASS_INVALID' => 'Il nome utente o la password non sono validi',
184184

185-
'WELCOME' => 'Bentornato, {{display_name}}'
185+
'WELCOME' => 'Bentornato, {{first_name}}'
186186
];

app/sprinkles/account/src/Account/Registration.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,15 @@ public function validate()
161161

162162
// Check if username is unique
163163
if (!$this->usernameIsUnique($this->userdata['user_name'])) {
164-
$e = new HttpException();
165-
$e->addUserMessage('USERNAME.IN_USE');
164+
$e = new HttpException('Username is already in use.');
165+
$e->addUserMessage('USERNAME.IN_USE', ['user_name' => $this->userdata['user_name']]);
166166
throw $e;
167167
}
168168

169169
// Check if email is unique
170170
if (!$this->emailIsUnique($this->userdata['email'])) {
171-
$e = new HttpException();
172-
$e->addUserMessage('EMAIL.IN_USE');
171+
$e = new HttpException('Email is already in use.');
172+
$e->addUserMessage('EMAIL.IN_USE', ['email' => $this->userdata['email']]);
173173
throw $e;
174174
}
175175

app/sprinkles/account/src/Controller/AccountController.php

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,22 @@ public function pageRegister(Request $request, Response $response, $args)
509509
// Get locale information
510510
$currentLocales = $localePathBuilder->getLocales();
511511

512+
// Hide the locale field if there is only 1 locale available
513+
$fields = [
514+
'hidden' => [],
515+
'disabled' => []
516+
];
517+
if (count($config->getDefined('site.locales.available')) <= 1) {
518+
$fields['hidden'][] = 'locale';
519+
}
520+
512521
return $this->ci->view->render($response, 'pages/register.html.twig', [
513522
'page' => [
514523
'validators' => [
515524
'register' => $validatorRegister->rules('json', false)
516525
]
517526
],
527+
'fields' => $fields,
518528
'locales' => [
519529
'available' => $config['site.locales.available'],
520530
'current' => end($currentLocales)
@@ -658,8 +668,18 @@ public function pageSettings(Request $request, Response $response, $args)
658668
// Get a list of all locales
659669
$locales = $config->getDefined('site.locales.available');
660670

671+
// Hide the locale field if there is only 1 locale available
672+
$fields = [
673+
'hidden' => [],
674+
'disabled' => []
675+
];
676+
if (count($config->getDefined('site.locales.available')) <= 1) {
677+
$fields['hidden'][] = 'locale';
678+
}
679+
661680
return $this->ci->view->render($response, 'pages/account-settings.html.twig', [
662681
'locales' => $locales,
682+
'fields' => $fields,
663683
'page' => [
664684
'validators' => [
665685
'account_settings' => $validatorAccountSettings->rules('json', false),
@@ -766,6 +786,11 @@ public function profile(Request $request, Response $response, $args)
766786

767787
$error = false;
768788

789+
// Ensure that in the case of using a single locale, that the locale is set
790+
if (count($config->getDefined('site.locales.available')) <= 1) {
791+
$data['locale'] = $currentUser->locale;
792+
}
793+
769794
// Validate, and halt on validation errors.
770795
$validator = new ServerSideValidator($schema, $this->ci->translator);
771796
if (!$validator->validate($data)) {
@@ -877,6 +902,11 @@ public function register(Request $request, Response $response, $args)
877902

878903
$error = false;
879904

905+
// Ensure that in the case of using a single locale, that the locale is set
906+
if (count($config->getDefined('site.locales.available')) <= 1) {
907+
$data['locale'] = $config['site.registration.user_defaults.locale'];
908+
}
909+
880910
// Validate request data
881911
$validator = new ServerSideValidator($schema, $this->ci->translator);
882912
if (!$validator->validate($data)) {
@@ -913,12 +943,9 @@ public function register(Request $request, Response $response, $args)
913943
// Now that we check the form, we can register the actual user
914944
$registration = new Registration($this->ci, $data);
915945

916-
try {
917-
$user = $registration->register();
918-
} catch (\Exception $e) {
919-
$ms->addMessageTranslated('danger', $e->getMessage(), $data);
920-
$error = true;
921-
}
946+
// Try registration. An HttpException will be thrown if it fails
947+
// No need to catch, as this kind of exception will automatically returns the addMessageTranslated
948+
$user = $registration->register();
922949

923950
// Success message
924951
if ($config['site.registration.require_email_verification']) {
@@ -1163,6 +1190,11 @@ public function settings(Request $request, Response $response, $args)
11631190

11641191
$error = false;
11651192

1193+
// Ensure that in the case of using a single locale, that the locale is set
1194+
if (count($config->getDefined('site.locales.available')) <= 1) {
1195+
$data['locale'] = $currentUser->locale;
1196+
}
1197+
11661198
// Validate, and halt on validation errors.
11671199
$validator = new ServerSideValidator($schema, $this->ci->translator);
11681200
if (!$validator->validate($data)) {

app/sprinkles/account/src/Database/Models/User.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,18 @@ public function delete($hardDelete = false)
188188
// Remove all role associations
189189
$this->roles()->detach();
190190

191-
// Remove all user activities
192-
$classMapper->staticMethod('activity', 'where', 'user_id', $this->id)->delete();
191+
// Remove last activity association
192+
$this->lastActivity()->dissociate();
193+
$this->save();
193194

194195
// Remove all user tokens
195-
$classMapper->staticMethod('password_reset', 'where', 'user_id', $this->id)->delete();
196+
$this->activities()->delete();
197+
$this->passwordResets()->delete();
196198
$classMapper->staticMethod('verification', 'where', 'user_id', $this->id)->delete();
197-
198-
// TODO: remove any persistences
199+
$classMapper->staticMethod('persistence', 'where', 'user_id', $this->id)->delete();
199200

200201
// Delete the user
201-
$result = parent::forceDelete();
202+
$result = $this->forceDelete();
202203
} else {
203204
// Soft delete the user, leaving all associated records alone
204205
$result = parent::delete();

app/sprinkles/account/src/Log/UserActivityDatabaseHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ protected function write(array $record)
2828

2929
if (isset($record['extra']['user_id'])) {
3030
$user = $this->classMapper->staticMethod('user', 'find', $record['extra']['user_id']);
31-
$user->last_activity_id = $log->id;
31+
$user->lastActivity()->associate($log);
3232
$user->save();
3333
}
3434
}

app/sprinkles/account/src/Repository/PasswordResetRepository.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace UserFrosting\Sprinkle\Account\Repository;
1111

12+
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
1213
use UserFrosting\Sprinkle\Account\Facades\Password;
1314

1415
/**
@@ -27,7 +28,7 @@ class PasswordResetRepository extends TokenRepository
2728
/**
2829
* {@inheritdoc}
2930
*/
30-
protected function updateUser($user, $args)
31+
protected function updateUser(UserInterface $user, $args)
3132
{
3233
$user->password = Password::hash($args['password']);
3334
// TODO: generate user activity? or do this in controller?

app/sprinkles/account/src/Repository/VerificationRepository.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
namespace UserFrosting\Sprinkle\Account\Repository;
1111

12+
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
13+
1214
/**
1315
* Token repository class for new account verifications.
1416
*
@@ -25,7 +27,7 @@ class VerificationRepository extends TokenRepository
2527
/**
2628
* {@inheritdoc}
2729
*/
28-
protected function updateUser($user, $args)
30+
protected function updateUser(UserInterface $user, $args)
2931
{
3032
$user->flag_verified = 1;
3133
// TODO: generate user activity? or do this in controller?

app/sprinkles/account/src/ServicesProvider/ServicesProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public function register(ContainerInterface $container)
6969
$classMapper->setClassMapping('activity', 'UserFrosting\Sprinkle\Account\Database\Models\Activity');
7070
$classMapper->setClassMapping('password_reset', 'UserFrosting\Sprinkle\Account\Database\Models\PasswordReset');
7171
$classMapper->setClassMapping('verification', 'UserFrosting\Sprinkle\Account\Database\Models\Verification');
72+
$classMapper->setClassMapping('persistence', 'UserFrosting\Sprinkle\Account\Database\Models\Persistence');
7273

7374
return $classMapper;
7475
});

app/sprinkles/account/templates/forms/settings-profile.html.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
</div>
2121
</div>
2222

23+
{% if 'locale' not in fields.hidden %}
2324
<div class="form-group">
2425
<label for="input-locale" class="control-label">{{translate("LOCALE")}}</label>
2526
<select id="input-locale" class="form-control js-select2" name="locale" {{page.visibility}}>
@@ -31,6 +32,7 @@
3132
</select>
3233
<p class="help-block">{{translate("LOCALE.ACCOUNT")}}.</p>
3334
</div>
35+
{% endif %}
3436
{% endblock %}
3537
</div>
3638
<div class="box-footer text-center">

app/sprinkles/account/templates/pages/register.html.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<label class="sr-only" for="r-form-passwordc">{{translate('PASSWORD.CONFIRM')}}</label>
5454
<input type="password" name="passwordc" placeholder="{{translate('PASSWORD.CONFIRM')}}" class="form-control" id="r-form-passwordc">
5555
</div>
56+
{% if 'locale' not in fields.hidden %}
5657
<div class="form-group">
5758
<label for="r-form-locale" class="control-label">{{translate("LOCALE")}}</label>
5859
<select id="r-form-locale" class="form-control js-select2" name="locale">
@@ -64,6 +65,7 @@
6465
</select>
6566
<p class="help-block">{{translate("LOCALE.ACCOUNT")}}.</p>
6667
</div>
68+
{% endif %}
6769
{% if site.registration.captcha %}
6870
<div class="form-group">
6971
<label class="sr-only" for="r-form-passwordc">{{translate('CAPTCHA.VERIFY')}}</label>

app/sprinkles/account/tests/Integration/AuthenticatorTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
use UserFrosting\Sprinkle\Account\Authenticate\Authenticator;
1313
use UserFrosting\Sprinkle\Account\Facades\Password;
1414
use UserFrosting\Sprinkle\Account\Tests\withTestUser;
15+
use UserFrosting\Sprinkle\Core\Database\Models\Session as SessionTable;
1516
use UserFrosting\Sprinkle\Core\Tests\TestDatabase;
1617
use UserFrosting\Sprinkle\Core\Tests\RefreshDatabase;
18+
use UserFrosting\Sprinkle\Core\Tests\withDatabaseSessionHandler;
1719
use UserFrosting\Tests\TestCase;
1820

1921
/**
@@ -26,6 +28,7 @@ class AuthenticatorTest extends TestCase
2628
use TestDatabase;
2729
use RefreshDatabase;
2830
use withTestUser;
31+
use withDatabaseSessionHandler;
2932

3033
/**
3134
* Setup the test database.
@@ -80,6 +83,54 @@ public function testLogin(Authenticator $authenticator)
8083
$this->assertNotSame($testUser->id, $this->ci->session[$key]);
8184
}
8285

86+
/**
87+
* @depends testConstructor
88+
* @param Authenticator $authenticator
89+
*/
90+
public function testLoginWithSessionDatabase(Authenticator $authenticator)
91+
{
92+
// Reset CI Session
93+
$this->useDatabaseSessionHandler();
94+
95+
// Create a test user
96+
$testUser = $this->createTestUser();
97+
98+
// Check the table
99+
$this->assertSame(0, SessionTable::count());
100+
101+
// Test session to avoid false positive
102+
$key = $this->ci->config['session.keys.current_user_id'];
103+
$this->assertNull($this->ci->session[$key]);
104+
$this->assertNotSame($testUser->id, $this->ci->session[$key]);
105+
106+
// Login the test user
107+
$authenticator->login($testUser, false);
108+
109+
// Test session to see if user was logged in
110+
$this->assertNotNull($this->ci->session[$key]);
111+
$this->assertSame($testUser->id, $this->ci->session[$key]);
112+
113+
// Close session to initiate write
114+
session_write_close();
115+
116+
// Check the table again
117+
$this->assertSame(1, SessionTable::count());
118+
119+
// Reopen session
120+
$this->ci->session->start();
121+
122+
// Must logout to avoid test issue
123+
$authenticator->logout(true);
124+
125+
// We'll test the logout system works too while we're at it (and depend on it)
126+
$key = $this->ci->config['session.keys.current_user_id'];
127+
$this->assertNull($this->ci->session[$key]);
128+
$this->assertNotSame($testUser->id, $this->ci->session[$key]);
129+
130+
// Make sure table entry has been removed
131+
$this->assertSame(0, SessionTable::count());
132+
}
133+
83134
/**
84135
* @depends testConstructor
85136
* @expectedException \UserFrosting\Sprinkle\Account\Authenticate\Exception\AccountInvalidException

0 commit comments

Comments
 (0)