Skip to content

Commit

Permalink
caching improvements, enable webhooks support
Browse files Browse the repository at this point in the history
  • Loading branch information
nivv committed Apr 22, 2024
1 parent eb24899 commit 23fd4fd
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 48 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"spatie/once": "^2.0|^3.0",
"pusher/pusher-php-server": "^7.0",
"aws/aws-sdk-php": "^3.219",
"laravel/pint": "^1.2"
"laravel/pint": "^1.2",
"spatie/laravel-webhook-server": "^3.8"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
Expand All @@ -69,4 +70,4 @@
"url": "https://github.com/KarabinSE/laravel-make-user"
}
}
}
}
6 changes: 6 additions & 0 deletions config/fabriq.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,10 @@
'ui' => [
'large_block_picker' => false,
],

'webhooks' => [
'enabled' => true,
'secret' => env('FABRIQ_WEBHOOK_SECRET'),
'endpoint' => env('FABRIQ_WEBHOOK_ENDPOINT'),
],
];
3 changes: 3 additions & 0 deletions src/EventServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Ikoncept\Fabriq;

use Ikoncept\Fabriq\Listeners\BustPageCacheListener;
use Ikoncept\Fabriq\Listeners\CallCacheBustingWebhook;
use Ikoncept\Fabriq\Listeners\FlushTagCacheListener;
use Ikoncept\Fabriq\Listeners\UpdateSlugListener;
use Illuminate\Auth\Events\Registered;
Expand All @@ -21,9 +22,11 @@ class EventServiceProvider extends ServiceProvider
],
DefinitionsUpdated::class => [
UpdateSlugListener::class,
CallCacheBustingWebhook::class,
],
DefinitionsPublished::class => [
BustPageCacheListener::class,
CallCacheBustingWebhook::class,
],
TranslatedRevisionDeleted::class => [
FlushTagCacheListener::class,
Expand Down
2 changes: 1 addition & 1 deletion src/FabriqCoreServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function boot()

$this->publishes([
__DIR__.'/../config/fortify.php' => config_path('fortify.php'),
], 'config');
], 'fortify-config');

$this->loadMigrationsFrom([realpath(__DIR__.'/../database/migrations')]);

Expand Down
5 changes: 1 addition & 4 deletions src/Http/Controllers/Api/Fabriq/ContactController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ class ContactController extends ApiController

/**
* Returns an index of contacts.
*
* @param Request $request
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
Expand Down Expand Up @@ -68,7 +65,7 @@ public function update(UpdateContactRequest $request, int $id): JsonResponse
'enabled_locales' => $request->content['enabled_locales'] ?? [],
], $request->input('locale', app()->getLocale()));

$contact->save();
$contact->saveQuietly();

return $this->respondWithItem($contact, Fabriq::getTransformerFor('contact'));
}
Expand Down
7 changes: 3 additions & 4 deletions src/Listeners/BustPageCacheListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@ public function __construct()
/**
* Handle the event.
*
* @param DefinitionsPublished $event
* @return void
*/
public function handle(DefinitionsPublished $event)
{
$tagName = Str::lower(class_basename($event->model));

Log::info('Flushing menu cache');
Cache::tags('cms_menu')->flush();
Cache::tags('fabriq_menu')->flush();

if (! $event->model->slugs) {
return;
}

foreach ($event->model->slugs as $slug) {
Log::info('Flushing page cache', ['name' => $event->model->name, 'key' => 'cms_'.$tagName.'_'.$slug->slug]);
Cache::tags('cms_'.$tagName.'_'.$slug->slug)->flush();
Log::info('Flushing page cache', ['name' => $event->model->name, 'key' => 'fabriq_'.$tagName.'_'.$slug->slug]);
Cache::tags('fabriq_'.$tagName.'_'.$slug->slug)->flush();
}
}
}
84 changes: 84 additions & 0 deletions src/Listeners/CallCacheBustingWebhook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace Ikoncept\Fabriq\Listeners;

use Ikoncept\Fabriq\Fabriq;
use Illuminate\Support\Facades\RateLimiter;
use Infab\TranslatableRevisions\Events\DefinitionsUpdated;
use Spatie\WebhookServer\WebhookCall;

class CallCacheBustingWebhook
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{

$model = $event->model;

if (! config('fabriq.webhooks.enabled')) {
return;
}

// Case for pages, skip busting on update
if (get_class($event) === DefinitionsUpdated::class && Fabriq::getFqnModel('page') === get_class($model)) {
return;
}

$tagsToFlush = collect($event->model->getRevisionOptions()->cacheTagsToFlush)->map(function ($tag) use ($model) {

Check failure on line 42 in src/Listeners/CallCacheBustingWebhook.php

View workflow job for this annotation

GitHub Actions / Laravel (PHP 8.3 on ubuntu-latest)

Unable to resolve the template type TKey in call to function collect

Check failure on line 42 in src/Listeners/CallCacheBustingWebhook.php

View workflow job for this annotation

GitHub Actions / Laravel (PHP 8.3 on ubuntu-latest)

Unable to resolve the template type TValue in call to function collect
$parts = explode('|', $tag);
if (isset($parts[1])) {
$key = $parts[1];

if ($key === 'slug' && $model->slugs) {

$slugs = collect([]);
foreach ($model->slugs as $slug) {
$slugs->push("{$parts[0]}_{$parts[1]}_{$slug->slug}");
}

return $slugs->toArray();
}

return "{$parts[0]}_{$parts[1]}_{$model->$key}";
}

return $tag;
})->flatten();

if (! $tagsToFlush->count()) {
return;
}

// 1 per 5 seconds for the same key
RateLimiter::attempt(
key: hash('adler32', json_encode($tagsToFlush)),
maxAttempts: 1,
callback: function () use ($tagsToFlush) {
WebhookCall::create()
->url(config('fabriq.webhooks.endpoint'))
->payload([
'type' => 'cache_expiration',
'invalid_cache_tags' => $tagsToFlush->toArray(),
])
->useSecret(config('fabriq.webhooks.secret'))
->dispatch();
},
decaySeconds: 1
);
}
}
4 changes: 2 additions & 2 deletions src/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

class Article extends Model
{
use HasFactory, HasTranslatedRevisions, BroadcastsEvents;
use BroadcastsEvents, HasFactory, HasTranslatedRevisions;

public const RELATIONSHIPS = ['template', 'template.fields', 'slugs'];

Expand Down Expand Up @@ -59,7 +59,7 @@ public function getRevisionOptions(): RevisionOptions
return RevisionOptions::create()
->registerDefaultTemplate('article')
->registerSpecialTypes(['image'])
->registerCacheTagsToFlush(['cms_articles'])
->registerCacheTagsToFlush(['fabriq_articles|slug'])
->registerGetters([
'image' => 'getImages',
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Models/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

class Contact extends Model
{
use HasFactory, HasTranslatedRevisions, HasTags, BroadcastsEvents;
use BroadcastsEvents, HasFactory, HasTags, HasTranslatedRevisions;

public const RELATIONSHIPS = ['images', 'tags'];

Expand Down Expand Up @@ -46,7 +46,7 @@ public function getRevisionOptions(): RevisionOptions
return RevisionOptions::create()
->registerDefaultTemplate('contact')
->registerSpecialTypes(['image'])
->registerCacheTagsToFlush(['cms_contacts'])
->registerCacheTagsToFlush(['fabriq_contacts'])
->registerGetters([
'image' => 'getImages',
]);
Expand Down
11 changes: 3 additions & 8 deletions src/Models/MenuItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class MenuItem extends Model
{
use HasFactory, NodeTrait, HasTranslatedRevisions;
use HasFactory, HasTranslatedRevisions, NodeTrait;

public const RELATIONSHIPS = ['page'];

Expand Down Expand Up @@ -66,7 +66,7 @@ public function getRevisionOptions(): RevisionOptions
{
return RevisionOptions::create()
->registerDefaultTemplate('menu-item')
->registerCacheTagsToFlush(['cms_menu']);
->registerCacheTagsToFlush(['fabriq_menu']);
}

public function page(): BelongsTo
Expand All @@ -76,8 +76,6 @@ public function page(): BelongsTo

/**
* Get the title attribute.
*
* @return string
*/
public function getTitleAttribute(): string
{
Expand All @@ -103,7 +101,6 @@ public function getSlugString(string $locale = '')
/**
* Get the slug.
*
* @param string $locale
* @return mixed
*/
public function getSlug(string $locale = '')
Expand All @@ -129,7 +126,7 @@ public function getRelativePathAttribute(): string
return;
}

return $carry.'/'.$subItem->getSlugString();
return $carry.'/'.$subItem->getSlugString();
}, '').'/'.$this->getSlugString();
}

Expand All @@ -140,7 +137,6 @@ public function getRelativePathAttribute(): string
* Skip setting title.
*
* @param mixed $value
* @return void
*/
public function setTitleAttribute($value): void
{
Expand All @@ -150,7 +146,6 @@ public function setTitleAttribute($value): void
* Skip setting page attribute.
*
* @param mixed $value
* @return void
*/
public function setPageAttribute($value): void
{
Expand Down
5 changes: 3 additions & 2 deletions src/Models/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

class Page extends Model implements HasMedia
{
use HasFactory, HasTranslatedRevisions, InteractsWithMedia, NodeTrait, Commentable, HasPaths, BroadcastsModelEvents;
use BroadcastsModelEvents, Commentable, HasFactory, HasPaths, HasTranslatedRevisions, InteractsWithMedia, NodeTrait;

public const RELATIONSHIPS = ['template', 'template.fields'];

Expand Down Expand Up @@ -113,7 +113,8 @@ public function getRevisionOptions(): RevisionOptions
'button' => 'getButton',
'buttons' => 'getButtons',
'smartBlock' => 'getSmartBlock',
]);
])
->registerCacheTagsToFlush(['fabriq_menu', 'fabriq_pages|slug']);
}

/**
Expand Down
11 changes: 1 addition & 10 deletions src/Models/SmartBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function getRevisionOptions(): RevisionOptions
'video' => 'getVideos',
])
->registerDefaultTemplate('smart_block')
->registerCacheTagsToFlush(['cms_pages', 'cms_smart_blocks']);
->registerCacheTagsToFlush(['fabriq_pages', 'fabriq_smart_blocks']);
}

/**
Expand All @@ -66,7 +66,6 @@ public function setLocalizedContentAttribute($value)
}

/**
* @param RevisionMeta $meta
* @return mixed
*/
public function getImages(RevisionMeta $meta)
Expand All @@ -75,7 +74,6 @@ public function getImages(RevisionMeta $meta)
}

/**
* @param RevisionMeta $meta
* @return mixed
*/
public function getFiles(RevisionMeta $meta)
Expand All @@ -84,7 +82,6 @@ public function getFiles(RevisionMeta $meta)
}

/**
* @param RevisionMeta $meta
* @return mixed
*/
public function getVideos(RevisionMeta $meta)
Expand All @@ -95,7 +92,6 @@ public function getVideos(RevisionMeta $meta)
/**
* Getter for button.
*
* @param RevisionMeta $meta
* @return mixed
*/
public function getButton(RevisionMeta $meta)
Expand All @@ -106,7 +102,6 @@ public function getButton(RevisionMeta $meta)
/**
* Getter for buttons.
*
* @param RevisionMeta $meta
* @return mixed
*/
public function getButtons(RevisionMeta $meta)
Expand All @@ -116,10 +111,6 @@ public function getButtons(RevisionMeta $meta)

/**
* Search for smart blocks.
*
* @param Builder $query
* @param string $search
* @return Builder
*/
public function scopeSearch(Builder $query, string $search): Builder
{
Expand Down
5 changes: 2 additions & 3 deletions src/Repositories/Decorators/CachingMenuRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ public function __construct(MenuRepositoryInterface $repository, Cache $cache)
/**
* Find by slug.
*
* @param string $slug
* @return mixed
*/
public function findBySlug(string $slug)
{
$locale = app()->getLocale();
$menu = $this->cache->tags(['cms_menu_'.$slug, 'cms_menu'])
$menu = $this->cache->tags(['fabriq_menu_'.$slug, 'fabriq_menu'])
->rememberForever($locale, function () use ($slug) {
Log::info('Caching menu', ['cache_key' => 'cms_menu_'.$slug, 'cms_menu']);
Log::info('Caching menu', ['cache_key' => 'fabriq_menu_'.$slug, 'fabriq_menu']);

return $this->repository->findBySlug($slug);
});
Expand Down
Loading

0 comments on commit 23fd4fd

Please sign in to comment.