-
-
Save lukasbestle/6a7d2d89448b096ad49404aac0b17d8f to your computer and use it in GitHub Desktop.
Kirby 3.4 hook migration checker plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Kirby 3.4 hook migration checker plugin | |
* Place this in `site/plugins/migration/index.php` | |
* and visit any frontend page of your Kirby site | |
* to check if you need to migrate some of your hooks. | |
* | |
* @version 2020-07-09 | |
* @package Kirby Cms | |
* @author Lukas Bestle <lukas@getkirby.com> | |
* @link https://getkirby.com | |
* @copyright Bastian Allgeier GmbH | |
* @license https://getkirby.com/license | |
*/ | |
Kirby::plugin('getkirby/kirby-3-4-migration', [ | |
'hooks' => [ | |
'system.loadPlugins:after' => function () { | |
$events = [ | |
'file.changeName:before' => ['file', 'name'], | |
'file.changeName:after' => ['newFile', 'oldFile'], | |
'file.changeSort:before' => ['file', 'position'], | |
'file.changeSort:after' => ['newFile', 'oldFile'], | |
'file.create:before' => ['file', 'upload'], | |
'file.create:after' => ['file'], | |
'file.delete:before' => ['file'], | |
'file.delete:after' => ['status', 'file'], | |
'file.replace:before' => ['file', 'upload'], | |
'file.replace:after' => ['newFile', 'oldFile'], | |
'file.update:before' => ['file', 'values', 'strings'], | |
'file.update:after' => ['newFile', 'oldFile'], | |
'kirbytags:before' => ['text', 'data', 'options'], | |
'kirbytags:after' => ['text', 'data', 'options'], | |
'kirbytext:before' => ['text'], | |
'kirbytext:after' => ['text'], | |
'page.changeNum:before' => ['page', 'num'], | |
'page.changeNum:after' => ['newPage', 'oldPage'], | |
'page.changeSlug:before' => ['page', 'slug', 'languageCode'], | |
'page.changeSlug:after' => ['newPage', 'oldPage'], | |
'page.changeStatus:before' => ['page', 'status', 'position'], | |
'page.changeStatus:after' => ['newPage', 'oldPage'], | |
'page.changeTemplate:before' => ['page', 'template'], | |
'page.changeTemplate:after' => ['newPage', 'oldPage'], | |
'page.changeTitle:before' => ['page', 'title', 'languageCode'], | |
'page.changeTitle:after' => ['newPage', 'oldPage'], | |
'page.create:before' => ['page', 'input'], | |
'page.create:after' => ['page'], | |
'page.delete:before' => ['page', 'force'], | |
'page.delete:after' => ['status', 'page'], | |
'page.duplicate:before' => ['originalPage', 'input', 'options'], | |
'page.duplicate:after' => ['duplicatePage'], | |
'page.update:before' => ['page', 'values', 'strings'], | |
'page.update:after' => ['newPage', 'oldPage'], | |
'route:before' => ['route', 'path', 'method'], | |
'route:after' => ['route', 'path', 'method', 'result'], | |
'site.changeTitle:before' => ['site', 'title', 'languageCode'], | |
'site.changeTitle:after' => ['newSite', 'oldSite'], | |
'site.update:before' => ['site', 'values', 'strings'], | |
'site.update:after' => ['newSite', 'oldSite'], | |
'system.loadPlugins:after' => [], | |
'user.changeEmail:before' => ['user', 'email'], | |
'user.changeEmail:after' => ['newUser', 'oldUser'], | |
'user.changeLanguage:before' => ['user', 'language'], | |
'user.changeLanguage:after' => ['newUser', 'oldUser'], | |
'user.changeName:before' => ['user', 'name'], | |
'user.changeName:after' => ['newUser', 'oldUser'], | |
'user.changePassword:before' => ['user', 'password'], | |
'user.changePassword:after' => ['newUser', 'oldUser'], | |
'user.changeRole:before' => ['user', 'role'], | |
'user.changeRole:after' => ['newUser', 'oldUser'], | |
'user.create:before' => ['user', 'input'], | |
'user.create:after' => ['user'], | |
'user.delete:before' => ['user'], | |
'user.delete:after' => ['status', 'user'], | |
'user.login:before' => ['user', 'session'], | |
'user.login:after' => ['user', 'session'], | |
'user.logout:before' => ['user', 'session'], | |
'user.logout:after' => ['user', 'session'], | |
'user.update:before' => ['user', 'values', 'strings'], | |
'user.update:after' => ['newUser', 'oldUser'] | |
]; | |
$results = []; | |
foreach ($events as $eventName => $expectedParameters) { | |
// request all registered hooks for this event type | |
$hooks = kirby()->extension('hooks', $eventName); | |
if (is_array($hooks) !== true) { | |
continue; | |
} | |
foreach ($hooks as $function) { | |
$reflection = new ReflectionFunction($function); | |
$parameters = array_map(function ($parameter) { | |
return $parameter->getName(); | |
}, $reflection->getParameters()); | |
$messages = []; | |
foreach ($parameters as $i => $parameter) { | |
// check for the event parameter | |
if ($parameter === 'event') { | |
$messages[] = '⚠️ The <code>$event</code> argument was added in Kirby 3.4.0. ' . | |
'If this hook was created before Kirby 3.4.0, this argument will now receive a different value.'; | |
} else { | |
// check for undefined parameters | |
if (in_array($parameter, $expectedParameters) !== true) { | |
$message = '‼️ The <a href="https://getkirby.com/docs/reference/plugins/hooks/' . Str::slug($eventName) . '"><code>' . | |
Html::encode($eventName) . '</code></a> event does not provide the <code>$' . Html::encode($parameter) . '</code> argument. '; | |
if (isset($expectedParameters[$i]) === true) { | |
$message .= 'Kirby versions before 3.4.0 have expected the argument <code>$' . Html::encode($expectedParameters[$i]) . '</code> in this position.'; | |
} else { | |
$message .= 'Kirby versions before 3.4.0 did not provide an argument at this position.'; | |
} | |
$messages[] = $message; | |
// check for wrong parameter order | |
} elseif ($i !== array_search($parameter, $expectedParameters)) { | |
$messages[] = '⚠️ The <code>$' . Html::encode($parameter) . '</code> argument is in a different position than it ' . | |
'<a href="https://getkirby.com/docs/reference/plugins/hooks/' . Str::slug($eventName) . '">needed to be before Kirby 3.4.0</a>. ' . | |
'If this hook was created before Kirby 3.4.0, this argument will now receive a different value – in this case please ' . | |
'rename your hook arguments (in the argument list <em>and</em> in the hook code itself) to match the documentation.'; | |
} | |
} | |
} | |
if (empty($messages) === false) { | |
$path = $reflection->getFileName() . ':' . $reflection->getStartLine(); | |
$path = str_replace(kirby()->root('index') . '/', '', $path); | |
$results[$path] = ['type' => $eventName, 'messages' => $messages]; | |
} | |
} | |
} | |
// sort the results by file path | |
ksort($results); | |
?> | |
<h1>Kirby 3.4 hook migration checker</h1> | |
<p><?= empty($results) === true ? '✅ No issues found, you are good to go. 🎉' : '🚨 We found some issues, please follow the instructions below. 🚨' ?></p> | |
<?php if (empty($results) === false): ?> | |
<ul> | |
<?php foreach ($results as $file => $data): ?> | |
<li> | |
<strong><?= $file ?></strong> <em>(<?= $data['type'] ?>)</em><br> | |
<?= implode('<br>', $data['messages']) ?> | |
</li> | |
<?php endforeach ?> | |
</ul> | |
<?php endif ?> | |
<style> | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; | |
padding: 2em 10%; | |
line-height: 1.5; | |
} | |
p { | |
margin-bottom: 2em; | |
} | |
li { | |
margin-bottom: 1em; | |
} | |
code { | |
background: #e8e8e8; | |
font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; | |
font-size: 0.875em; | |
border-radius: 3px; | |
padding: 0.05em 0.5em; | |
} | |
</style> | |
<?php | |
die(); | |
} | |
] | |
]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment