Skip to content

Commit c8d6290

Browse files
committed
Merge remote-tracking branch 'origin/hotfix' into develop
2 parents 7ba72c2 + 77dfd35 commit c8d6290

8 files changed

Lines changed: 128 additions & 4 deletions

File tree

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ before_install:
3333
- nvm install 10.12.0
3434
# Install Redis and Memcached
3535
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
36-
- printf "\n" | pecl install -f redis
36+
# Temporary disabled as it's not compatible with PHP 5.6
37+
# - printf "\n" | pecl install -f redis
3738

3839
before_script:
3940
# install deps and UF

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
5252
### Added
5353
- Config to set Domain of RememberMe Cookie ([#990], [#991]; Thanks @xrobau !)
5454
- Config settings for password min/max length ([#993])
55+
- `migrate:clean` bakery command ([#1007])
5556

5657
### Fixed
5758
- [PHPMailer] Turn off opportunistic TLS when disabled ([#986], [#987])
5859
- Migrator now ignore files that don't end in `.php` ([#965], [#998])
5960
- Respects CSRF_ENABLED environment variable ([#976]; Thanks @Poldovico !)
61+
- Checkbox bug on password change form ([#1008])
62+
- On role page, users table action buttons not working ([#1010])
6063

6164
## [v4.2.2]
6265

@@ -829,6 +832,9 @@ See [http://learn.userfrosting.com/upgrading/40-to-41](Upgrading 4.0.x to 4.1.x
829832
[#993]: https://github.com/userfrosting/UserFrosting/issues/993
830833
[#994]: https://github.com/userfrosting/UserFrosting/issues/994
831834
[#998]: https://github.com/userfrosting/UserFrosting/issues/998
835+
[#1007]: https://github.com/userfrosting/UserFrosting/issues/1007
836+
[#1008]: https://github.com/userfrosting/UserFrosting/issues/1008
837+
[#1010]: https://github.com/userfrosting/UserFrosting/issues/1010
832838
[#1012]: https://github.com/userfrosting/UserFrosting/issues/1012
833839
[#1014]: https://github.com/userfrosting/UserFrosting/issues/1014
834840
[#1015]: https://github.com/userfrosting/UserFrosting/issues/1015

app/sprinkles/admin/asset-bundles.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
},
7676
"js/pages/role": {
7777
"scripts": [
78+
"userfrosting/js/widgets/users.js",
7879
"userfrosting/js/widgets/roles.js",
7980
"userfrosting/js/pages/role.js"
8081
],

app/sprinkles/admin/assets/userfrosting/js/pages/role.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ $(document).ready(function() {
2020
dataUrl: site.uri.public + '/api/roles/r/' + page.role_slug + '/users',
2121
useLoadingTransition: site.uf_table.use_loading_transition
2222
});
23+
24+
// Bind table buttons
25+
$("#widget-role-users").on("pagerComplete.ufTable", function () {
26+
bindUserButtons($(this));
27+
});
2328
});

app/sprinkles/admin/assets/userfrosting/js/widgets/users.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,6 @@ function bindUserButtons(el, options) {
266266

267267
// On submission, submit either the PUT request, or POST for a password reset, depending on the toggle state
268268
modal.find("input[name='change_password_mode']").click(function(e) {
269-
e.preventDefault();
270269

271270
var changePasswordMode = $(this).val();
272271
toggleChangePasswordMode(modal, userName, changePasswordMode);
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
/*
4+
* UserFrosting (http://www.userfrosting.com)
5+
*
6+
* @link https://github.com/userfrosting/UserFrosting
7+
* @copyright Copyright (c) 2019 Alexander Weissman
8+
* @license https://github.com/userfrosting/UserFrosting/blob/master/LICENSE.md (MIT License)
9+
*/
10+
11+
namespace UserFrosting\Sprinkle\Core\Bakery;
12+
13+
use Illuminate\Support\Collection;
14+
use Symfony\Component\Console\Input\InputInterface;
15+
use Symfony\Component\Console\Input\InputOption;
16+
use Symfony\Component\Console\Output\OutputInterface;
17+
use UserFrosting\Sprinkle\Core\Database\Migrator\Migrator;
18+
19+
/**
20+
* migrate:clean Bakery Command
21+
* Remove stale migrations from the database.
22+
*
23+
* @author Amos Folz
24+
*/
25+
class MigrateCleanCommand extends MigrateCommand
26+
{
27+
/**
28+
* {@inheritdoc}
29+
*/
30+
protected function configure()
31+
{
32+
$this->setName('migrate:clean')
33+
->setDescription('Remove stale migrations from the database.')
34+
->setHelp('Removes stale migrations, which are simply migration class files that have been removed from the Filesystem. E.g. if you run a migration and then delete the migration class file prior to running `down()` for that migration it becomes stale. If a migration is a dependency of another migration you probably want to try to restore the files instead of running this command to avoid further issues.')
35+
->addOption('database', 'd', InputOption::VALUE_REQUIRED, 'The database connection to use.')
36+
->addOption('force', 'f', InputOption::VALUE_NONE, 'Do not prompt for confirmation.');
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
protected function execute(InputInterface $input, OutputInterface $output)
43+
{
44+
$this->io->title('Migration clean');
45+
46+
// Get migrator
47+
$migrator = $this->ci->migrator;
48+
49+
// Set connection to the selected database
50+
$migrator->setConnection($input->getOption('database'));
51+
52+
// Get ran migrations. If repository doesn't exist, there's no ran
53+
if (!$migrator->repositoryExists()) {
54+
$ran = collect();
55+
} else {
56+
$ran = $migrator->getRepository()->getMigrations();
57+
}
58+
59+
// Get available migrations
60+
$available = $migrator->getAvailableMigrations();
61+
62+
$stale = $this->getStaleRecords($ran, $available);
63+
64+
if ($stale->count() > 0) {
65+
if (!$input->getOption('force')) {
66+
$this->io->section('Stale migrations');
67+
$this->io->listing($stale->toArray());
68+
69+
if (!$this->io->confirm('Continue and remove stale migrations?', false)) {
70+
exit;
71+
}
72+
}
73+
$this->io->section('Cleaned migrations');
74+
$this->cleanStaleRecords($stale, $migrator);
75+
$this->io->listing($stale->toArray());
76+
} else {
77+
$this->io->note('No stale migrations');
78+
}
79+
}
80+
81+
/**
82+
* Delete stale migrations from the database.
83+
*
84+
* @param Collection $stale Collection of stale migartion classes.
85+
* @param Migrator $migrator Migrator object
86+
*/
87+
protected function cleanStaleRecords(Collection $stale, Migrator $migrator)
88+
{
89+
$migrationRepository = $migrator->getRepository();
90+
91+
//Delete the stale migration classes from the database.
92+
$stale->each(function ($class) use ($migrationRepository) {
93+
$migrationRepository->delete($class);
94+
});
95+
}
96+
97+
/**
98+
* Return an array of stale migrations.
99+
* A migration is stale if not found in the available stack (class is not in the Filesystem).
100+
*
101+
* @param Collection $ran The ran migrations
102+
* @param array $available The available migrations
103+
*
104+
* @return Collection Collection of stale migration classes.
105+
*/
106+
protected function getStaleRecords(Collection $ran, array $available)
107+
{
108+
return $filtered = collect($ran)->filter(function ($migration) use ($available) {
109+
return !in_array($migration->migration, $available);
110+
})->pluck('migration');
111+
}
112+
}

app/sprinkles/core/src/Database/Migrator/MigrationDependencyAnalyser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ protected function getMigrationDependencies($migration)
210210

211211
// Make sure class exists
212212
if (!class_exists($migration)) {
213-
throw new BadClassNameException("Unable to find the migration class '$migration'.");
213+
throw new BadClassNameException("Unable to find the migration class '$migration'. Run 'php bakery migrate:clean' to remove stale migrations.");
214214
}
215215

216216
// If the `dependencies` property exist and is static, use this one.

app/sprinkles/core/src/Database/Migrator/Migrator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ protected function getQueries(MigrationInterface $migration, $method)
453453
public function resolve($migrationClassName)
454454
{
455455
if (!class_exists($migrationClassName)) {
456-
throw new BadClassNameException("Unable to find the migration class '$migrationClassName'.");
456+
throw new BadClassNameException("Unable to find the migration class '$migrationClassName'. Run 'php bakery migrate:clean' to remove stale migrations.");
457457
}
458458

459459
$migration = new $migrationClassName($this->getSchemaBuilder());

0 commit comments

Comments
 (0)