Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Flarum events to purge LSCache to support CLI and HTTP contexts #30

Merged
merged 38 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4e4ef56
chore: bump a minimum PHP version to 8.1
rafaucau Sep 7, 2024
e115694
feat: use events to purge LSCache
rafaucau Sep 7, 2024
7098ac7
Apply fixes from StyleCI
StyleCIBot Sep 7, 2024
d68515d
fix: commit missing file
rafaucau Sep 7, 2024
8ac8952
Apply fixes from StyleCI
StyleCIBot Sep 7, 2024
8dcb8f1
ci: update PHP version
rafaucau Sep 7, 2024
dd7bdf8
feat: add Post event liteners
rafaucau Sep 8, 2024
0b60528
perf: enable native_function_invocation
rafaucau Sep 8, 2024
783c725
fix: remove risky function
rafaucau Sep 8, 2024
17135d8
feat: add User event listeners
rafaucau Sep 8, 2024
9d9a5fb
feat: add support for flarum/approval
rafaucau Sep 8, 2024
20113b8
feat: add support for flarum/likes
rafaucau Sep 8, 2024
5faf90f
feat: add support for flarum/tags
rafaucau Sep 8, 2024
83ad085
Apply fixes from StyleCI
StyleCIBot Sep 8, 2024
b209238
feat: add support for fof/masquerade
rafaucau Sep 8, 2024
c396343
feat: add support for v17development/blog
rafaucau Sep 8, 2024
73e2949
feat: add support for clarkwinkelmann/flarum-ext-author-change
rafaucau Sep 12, 2024
f65b2b2
Apply fixes from StyleCI
StyleCIBot Sep 12, 2024
0e21077
feat: add LSCachePurging event
rafaucau Sep 12, 2024
2148fd1
Apply fixes from StyleCI
StyleCIBot Sep 12, 2024
dbc1774
feat: add actor LSCachePurging event
rafaucau Sep 12, 2024
1fea496
style: group some imports
rafaucau Sep 12, 2024
6ed78e2
Apply fixes from StyleCI
StyleCIBot Sep 12, 2024
7dea0ec
fix: LSTagsMiddleware name
rafaucau Sep 12, 2024
11d31ea
refactor: update extension namespace
rafaucau Sep 12, 2024
2d7dcfe
refactor: add support for sycho/flarum-move-posts
rafaucau Sep 12, 2024
e79ebd9
refactor: simplify code
rafaucau Sep 12, 2024
b856870
chore: ignore some external PHPStan errors
rafaucau Sep 13, 2024
34858e0
feat: purge list from settings
rafaucau Sep 13, 2024
241bf46
style: cleanup code
rafaucau Sep 13, 2024
ae99a27
feat: use purge list settings in all discussion related subscribers
rafaucau Sep 13, 2024
6d40489
style: organize imports
rafaucau Sep 13, 2024
7b59477
feat: push purge command to queue
rafaucau Sep 13, 2024
337c001
Apply fixes from StyleCI
StyleCIBot Sep 13, 2024
1de0fc9
feat: generate less tags
rafaucau Sep 13, 2024
6445a9e
refactor: simplify code
rafaucau Sep 13, 2024
7c47230
Apply fixes from StyleCI
StyleCIBot Sep 13, 2024
e095732
fix: use user Deleting event instead of Deleted to access user posts
rafaucau Sep 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ jobs:
with:
enable_backend_testing: false
enable_phpstan: true
php_versions: '["8.0", "8.1", "8.2", "8.3"]'
php_versions: '["8.1", "8.2", "8.3"]'

backend_directory: .
19 changes: 14 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@
],
"require": {
"flarum/core": "^1.8",
"php": ">=8.0"
"php": ">=8.1"
},
"require-dev": {
"flarum/phpstan": "^1.8",
"flarum/tags": "*",
"v17development/flarum-blog": "^0.7.7"
"flarum/tags": "^1.8",
"v17development/flarum-blog": "^0.7.7",
"flarum/approval": "^1.8",
"flarum/likes": "^1.8",
"fof/masquerade": "^2.1",
"clarkwinkelmann/flarum-ext-author-change": "^1.0",
"sycho/flarum-move-posts": "^0.1.7"
},
"suggest": {
"blomstra/flarum-redis": "This library allows using Redis as cache, session and for the queue. https://github.com/blomstra/flarum-redis#set-up"
Expand All @@ -41,7 +46,7 @@
],
"autoload": {
"psr-4": {
"ACPL\\FlarumCache\\": "src/"
"ACPL\\FlarumLSCache\\": "src/"
}
},
"extra": {
Expand All @@ -54,9 +59,13 @@
"color": "#fff"
},
"optional-dependencies": [
"flarum/approval",
"flarum/tags",
"flarum/likes",
"fof/masquerade"
"fof/masquerade",
"v17development/flarum-blog",
"clarkwinkelmann/flarum-ext-author-change",
"sycho/flarum-move-posts"
]
},
"flarum-cli": {
Expand Down
88 changes: 51 additions & 37 deletions extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,32 @@
* file that was distributed with this source code.
*/

namespace ACPL\FlarumCache;
namespace ACPL\FlarumLSCache;

use ACPL\FlarumCache\Api\Controller\LSCacheCsrfResponseController;
use ACPL\FlarumCache\Api\Controller\PurgeLSCacheController;
use ACPL\FlarumCache\Command\LSCacheClearCommand;
use ACPL\FlarumCache\Compatibility\Flarum\Likes\FlarumLikesPurgeMiddleware;
use ACPL\FlarumCache\Compatibility\Flarum\Tags\FlarumTagsPurgeMiddleware;
use ACPL\FlarumCache\Compatibility\FriendsOfFlarum\Masquerade\FofMasqueradePurgeMiddleware;
use ACPL\FlarumCache\Compatibility\v17development\FlarumBlog\FlarumBlogPurgeMiddleware;
use ACPL\FlarumCache\Listener\ClearingCacheListener;
use ACPL\FlarumCache\Middleware\LoginMiddleware;
use ACPL\FlarumCache\Middleware\LogoutMiddleware;
use ACPL\FlarumCache\Middleware\LSCacheControlMiddleware;
use ACPL\FlarumCache\Middleware\LSCachePurgeMiddleware;
use ACPL\FlarumCache\Middleware\LSTagsMiddleware;
use ACPL\FlarumCache\Middleware\VaryCookieMiddleware;
use ACPL\FlarumLSCache\Api\Controller\{LSCacheCsrfResponseController, PurgeLSCacheController};
use ACPL\FlarumLSCache\Command\LSCachePurgeCommand;
use ACPL\FlarumLSCache\Compatibility\{
ClarkWinkelmann\AuthorChange\ClarkWinkelmannAuthorChangeEventSubscriber,
Flarum\Likes\FlarumLikesEventSubscriber,
Flarum\Tags\FlarumTagsEventSubscriber,
FriendsOfFlarum\Masquerade\FofMasqueradePurgeCacheMiddleware,
SychO\MovePosts\SychOMovePostsSubscriber,
v17development\FlarumBlog\FlarumBlogEventSubscriber
};
use ACPL\FlarumLSCache\Listener\{
ClearingCacheListener,
DiscussionEventSubscriber,
PostEventSubscriber,
UserEventSubscriber
};
use ACPL\FlarumLSCache\Middleware\{
CacheControlMiddleware,
CacheTagsMiddleware,
LoginMiddleware,
LogoutMiddleware,
PurgeCacheMiddleware,
VaryCookieMiddleware
};
use Flarum\Extend;
use Flarum\Foundation\Event\ClearingCache;
use Flarum\Http\Middleware\CheckCsrfToken;
Expand All @@ -41,7 +51,7 @@
->default('acpl-lscache.public_cache_ttl', 604_800)
->default('acpl-lscache.clearing_cache_listener', true)
->default('acpl-lscache.drop_qs', implode("\n", LSCache::DEFAULT_DROP_QS)),
(new Extend\Event())->listen(Saved::class, Listener\UpdateSettings::class),
(new Extend\Event())->listen(Saved::class, Listener\UpdateSettingsListener::class),

// Vary cookie
(new Extend\Middleware('forum'))->insertAfter(CheckCsrfToken::class, VaryCookieMiddleware::class),
Expand All @@ -53,43 +63,47 @@
(new Extend\Middleware('forum'))->insertAfter(VaryCookieMiddleware::class, LogoutMiddleware::class),

// Tag routes
(new Extend\Middleware('forum'))->add(LSTagsMiddleware::class),
(new Extend\Middleware('api'))->add(LSTagsMiddleware::class),
(new Extend\Middleware('forum'))->add(CacheTagsMiddleware::class),
(new Extend\Middleware('api'))->add(CacheTagsMiddleware::class),

// Cache routes
(new Extend\Middleware('forum'))->insertAfter(VaryCookieMiddleware::class, LSCacheControlMiddleware::class),
(new Extend\Middleware('api'))->insertAfter(VaryCookieMiddleware::class, LSCacheControlMiddleware::class),
(new Extend\Middleware('forum'))->insertAfter(VaryCookieMiddleware::class, CacheControlMiddleware::class),
(new Extend\Middleware('api'))->insertAfter(VaryCookieMiddleware::class, CacheControlMiddleware::class),

// A workaround for the CSRF cache issue. The JS script fetches this path to update the CSRF
(new Extend\Routes('api'))->get('/lscache-csrf', 'lscache.csrf', LSCacheCsrfResponseController::class),

// Purge cache on update
(new Extend\Middleware('forum'))->add(LSCachePurgeMiddleware::class),
(new Extend\Middleware('admin'))->add(LSCachePurgeMiddleware::class),
(new Extend\Middleware('api'))->add(LSCachePurgeMiddleware::class),
(new Extend\Middleware('forum'))->add(PurgeCacheMiddleware::class),
(new Extend\Middleware('admin'))->add(PurgeCacheMiddleware::class),
(new Extend\Middleware('api'))->add(PurgeCacheMiddleware::class),

// Purge cache
(new Extend\Routes('api'))->get('/lscache-purge', 'lscache.purge', PurgeLSCacheController::class),
(new Extend\Console())->command(LSCacheClearCommand::class),
(new Extend\Event())->listen(ClearingCache::class, ClearingCacheListener::class),
(new Extend\Console)->command(LSCachePurgeCommand::class),
(new Extend\Event)->listen(ClearingCache::class, ClearingCacheListener::class),

(new Extend\Event)->subscribe(DiscussionEventSubscriber::class),
(new Extend\Event)->subscribe(PostEventSubscriber::class),
(new Extend\Event)->subscribe(UserEventSubscriber::class),

// Compatibility with extensions
(new Extend\Conditional)
->whenExtensionEnabled('flarum-tags', [
(new Extend\Middleware('api'))->add(FlarumTagsPurgeMiddleware::class),
])
->whenExtensionEnabled('flarum-likes', [
(new Extend\Middleware('api'))->add(FlarumLikesPurgeMiddleware::class),
(new Extend\Event)->subscribe(FlarumLikesEventSubscriber::class),
])
->whenExtensionEnabled('flarum-tags', [
(new Extend\Event)->subscribe(FlarumTagsEventSubscriber::class),
])
->whenExtensionEnabled('fof-masquerade', [
(new Extend\Middleware('api'))->add(FofMasqueradePurgeMiddleware::class),
(new Extend\Middleware('api'))->add(FofMasqueradePurgeCacheMiddleware::class),
])
->whenExtensionEnabled('v17development-blog', [
// Using insertBefore enables reading headers set by LSCachePurgeMiddleware, while insertAfter does not.
// This suggests Flarum processes middleware in a reverse order 🤔.
(new Extend\Middleware('api'))->insertBefore(
LSCachePurgeMiddleware::class,
FlarumBlogPurgeMiddleware::class
),
(new Extend\Event)->subscribe(FlarumBlogEventSubscriber::class),
])
->whenExtensionEnabled('clarkwinkelmann-author-change', [
(new Extend\Event)->subscribe(ClarkWinkelmannAuthorChangeEventSubscriber::class),
])
->whenExtensionEnabled('sycho-move-posts', [
(new Extend\Event)->subscribe(SychOMovePostsSubscriber::class),
]),
];
4 changes: 2 additions & 2 deletions locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ acpl-lscache:
serve_stale_label: "Serve Stale Content"
serve_stale_help: "If enabled, an outdated version of a cached page will be served to visitors until a fresh cache copy is generated. This reduces server load. If disabled, the page will be dynamically generated during the cache update, which may increase wait times. By design, this option can serve out-of-date content. Please do not enable this if you find that unacceptable."

purge_on_discussion_update_label: "Purge URLs or Tags on Discussion or Post Update"
purge_on_discussion_update_help: "Enter the URLs or Tags you want to purge when a discussion or post is updated, one per line. URL should start with <code>/</code>, e.g. <code>/rankings</code>, and cache Tag should start with <code>tag=</code>, e.g. <code>tag=rankings</code>. For multiple routes, adding a rule in .htaccess with a regular expression that tags routes and entering only this tag here is faster. <a>Learn more</a>. By default, the cache for the homepage and updated discussions is purged."
purge_on_discussion_update_label: "Purge URLs or cache Tags on Discussion Update"
purge_on_discussion_update_help: "Enter the URLs or cache Tags you want to purge when a discussion is updated, one per line. URL should start with <code>/</code>, e.g. <code>/rankings</code>, and cache Tag should start with <code>tag=</code>, e.g. <code>tag=rankings</code>. For multiple routes, adding a rule in .htaccess with a regular expression that tags routes and entering only this tag here is faster. <a>Learn more</a>. By default, the cache for the homepage and updated discussions is purged."

cache_exclude_label: "Exclude Paths from Caching"
cache_exclude_help: "Paths containing these strings will not be cached. For <code>/mypath/mypage?aa=bb</code>, you can use <code>mypage?aa=</code>. To match the beginning, add <code>^</code> at the start. For an exact match, add <code>$</code> at the end of the URL. One per line."
Expand Down
4 changes: 2 additions & 2 deletions migrations/2023_05_16_000001_update_htaccess.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

use ACPL\FlarumCache\Utility\HtaccessManager;
use ACPL\FlarumLSCache\Utility\HtaccessManager;
use Flarum\Foundation\Paths;
use Flarum\Http\CookieFactory;
use Flarum\Settings\SettingsRepositoryInterface;
Expand All @@ -22,5 +22,5 @@ function lsCacheGetHtaccessManager(): HtaccessManager
'down' => function () {
$htaccessManager = lsCacheGetHtaccessManager();
$htaccessManager->removeLsCacheBlock();
}
},
];
81 changes: 0 additions & 81 deletions src/Abstract/PurgeMiddleware.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Api/Controller/LSCacheCsrfResponseController.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace ACPL\FlarumCache\Api\Controller;
namespace ACPL\FlarumLSCache\Api\Controller;

use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ResponseInterface;
Expand Down
6 changes: 3 additions & 3 deletions src/Api/Controller/PurgeLSCacheController.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

namespace ACPL\FlarumCache\Api\Controller;
namespace ACPL\FlarumLSCache\Api\Controller;

use ACPL\FlarumCache\LSCacheHeadersEnum;
use ACPL\FlarumLSCache\LSCacheHeader;
use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface;
use Flarum\User\Exception\PermissionDeniedException;
Expand Down Expand Up @@ -54,6 +54,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface
$purgeStr .= '*';
}

return (new EmptyResponse())->withHeader(LSCacheHeadersEnum::PURGE, $purgeStr);
return (new EmptyResponse())->withHeader(LSCacheHeader::PURGE, $purgeStr);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace ACPL\FlarumCache\Command;
namespace ACPL\FlarumLSCache\Command;

use Flarum\Api\ApiKey;
use Flarum\Console\AbstractCommand;
Expand All @@ -10,7 +10,7 @@
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\Console\Input\InputOption;

class LSCacheClearCommand extends AbstractCommand
class LSCachePurgeCommand extends AbstractCommand
{
protected UrlGenerator $url;
private SettingsRepositoryInterface $settings;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace ACPL\FlarumLSCache\Compatibility\ClarkWinkelmann\AuthorChange;

use ACPL\FlarumLSCache\Listener\{AbstractCachePurgeSubscriber, DiscussionCachePurgeTrait};
use ClarkWinkelmann\AuthorChange\Event\{
DiscussionCreateDateChanged,
DiscussionUserChanged,
PostCreateDateChanged,
PostEditDateChanged,
PostUserChanged
};
use Illuminate\Contracts\Events\Dispatcher;

class ClarkWinkelmannAuthorChangeEventSubscriber extends AbstractCachePurgeSubscriber
{
use DiscussionCachePurgeTrait;

public function subscribe(Dispatcher $events): void
{
$this->addPurgeListener($events, DiscussionCreateDateChanged::class, [$this, 'handleDiscussion']);
$this->addPurgeListener($events, DiscussionUserChanged::class, [$this, 'handleDiscussionUserChanged']);
$this->addPurgeListener($events, PostCreateDateChanged::class, [$this, 'handlePost']);
$this->addPurgeListener($events, PostEditDateChanged::class, [$this, 'handlePost']);
$this->addPurgeListener($events, PostUserChanged::class, [$this, 'handlePostUserChanged']);
}

protected function handleDiscussion(DiscussionCreateDateChanged|DiscussionUserChanged $event): void
{
$this->handleDiscussionRelatedPurge();
$this->purger->addPurgeTags([
"discussion_{$event->discussion->id}",
"user_{$event->discussion->user->id}",
"user_{$event->discussion->user->username}",
]);
}

protected function handleDiscussionUserChanged(DiscussionUserChanged $event): void
{
$this->handleDiscussion($event);
$this->purger->addPurgeTags([
"user_{$event->oldUser->id}",
"user_{$event->oldUser->username}",
]);
}

protected function handlePost(PostCreateDateChanged|PostEditDateChanged|PostUserChanged $event): void
{
$this->purger->addPurgeTags([
"discussion_{$event->post->discussion->id}",
'posts.index',
"post_{$event->post->id}",
"user_{$event->post->user->id}",
"user_{$event->post->user->username}",
]);
}

protected function handlePostUserChanged(PostUserChanged $event): void
{
$this->handlePost($event);
$this->purger->addPurgeTags([
"user_{$event->oldUser->id}",
"user_{$event->oldUser->username}",
]);
}
}
Loading
Loading