Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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/fix-php-code-style-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.head_ref }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:
- 6379:6379
options: --entrypoint redis-server
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
php-version: '8.5'
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick
coverage: none

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: main

Expand Down
4 changes: 2 additions & 2 deletions app/Actions/HandlePostSavedAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ public function execute(Post $post): void
(new PublishPostAction)->execute($post);
});

if (config('openai.api_key')) {
if (config('ai.providers.openai.key')) {
Bus::chain([
// new GeneratePostEmbeddingJob($post),
// new ComputeRelatedPostsJob($post),
])->dispatch();
}

if (config('prism.providers.anthropic.api_key') && $post->tags->isEmpty()) {
if (config('ai.providers.anthropic.key') && $post->tags->isEmpty()) {
GeneratePostTagsJob::dispatch($post);
}

Expand Down
45 changes: 45 additions & 0 deletions app/Ai/Agents/PostTagger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace App\Ai\Agents;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;
use Stringable;

class PostTagger implements Agent, HasStructuredOutput
{
use Promptable;

public function __construct(
private readonly string $existingTags,
) {}

public function instructions(): Stringable|string
{
return <<<PROMPT
You are a blog post tagger. Given a blog post, return 1 to 5 relevant tags.

Existing tags in the database: {$this->existingTags}

Rules:
- Strongly prefer tags from the existing list above.
- Only suggest a new tag if none of the existing tags are a good fit.
- Do NOT include the tag "tweet" — that tag is reserved for a special post type.
- All tags must be lowercase.
- If content is laravel related, include the "laravel" tag.
- If content is php related, include the "php" tag.
- If content is about AI, LLMs, machine learning, or related topics, include the "ai" tag.
- If the post is about a Spatie package (e.g. spatie/laravel-*, spatie/*, or mentions Spatie as the author), include the "spatie" tag.
- Never use version numbers in tags. Use "php" not "php8", "laravel" not "laravel11", etc. If a post currently has a versioned tag like "php8", replace it with "php".
PROMPT;
}

public function schema(JsonSchema $schema): array
{
return [
'tags' => $schema->array()->items($schema->string())->required(),
];
}
}
4 changes: 2 additions & 2 deletions app/Console/Commands/ComputeRelatedPostsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

use App\Jobs\ComputeRelatedPostsJob;
use App\Models\Post;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('app:compute-related-posts')]
class ComputeRelatedPostsCommand extends Command
{
protected $signature = 'app:compute-related-posts';

public function handle(): void
{
$count = 0;
Expand Down
4 changes: 2 additions & 2 deletions app/Console/Commands/GenerateEmbeddingsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

use App\Jobs\GeneratePostEmbeddingJob;
use App\Models\Post;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('app:generate-embeddings {--force : Regenerate embeddings for all posts}')]
class GenerateEmbeddingsCommand extends Command
{
protected $signature = 'app:generate-embeddings {--force : Regenerate embeddings for all posts}';

public function handle(): void
{
$query = Post::query()->published();
Expand Down
4 changes: 2 additions & 2 deletions app/Console/Commands/GenerateNewsletterCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
namespace App\Console\Commands;

use App\Actions\GenerateNewsletterAction;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('newsletter:generate')]
class GenerateNewsletterCommand extends Command
{
protected $signature = 'newsletter:generate';

public function handle(GenerateNewsletterAction $action): int
{
$result = $action->execute();
Expand Down
8 changes: 4 additions & 4 deletions app/Console/Commands/PerformHtmlConversionCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
use App\Models\Ad;
use App\Models\Post;
use App\Models\Video;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('blog:perform-html-conversion')]
#[Description('Convert post text to HTML')]
class PerformHtmlConversionCommand extends Command
{
protected $signature = 'blog:perform-html-conversion';

protected $description = 'Command description';

public function handle(): void
{
$this->info('Performing HTML conversions...');
Expand Down
8 changes: 4 additions & 4 deletions app/Console/Commands/PreheatOgImagesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
namespace App\Console\Commands;

use App\Models\Post;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Spatie\OgImage\Facades\OgImage;
use Throwable;

#[Signature('app:preheat-og-images')]
#[Description('Pre-generate OG images for all public pages')]
class PreheatOgImagesCommand extends Command
{
protected $signature = 'app:preheat-og-images';

protected $description = 'Pre-generate OG images for all public pages';

public function handle(): void
{
$urls = $this->collectUrls();
Expand Down
10 changes: 5 additions & 5 deletions app/Console/Commands/PublishScheduledPostsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

use App\Actions\PublishPostAction;
use App\Models\Post;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('blog:publish-scheduled-posts')]
#[Description('Publish scheduled posts')]
class PublishScheduledPostsCommand extends Command
{
protected $signature = 'blog:publish-scheduled-posts';

protected $description = 'Publish scheduled posts';

public function handle(PublishPostAction $publishPostAction): void
{
Post::scheduled()->get()
Post::query()->scheduled()->get()
->reject(fn (Post $post) => $post->publish_date->isFuture())
->each(fn (Post $post) => $publishPostAction->execute($post));
}
Expand Down
8 changes: 4 additions & 4 deletions app/Console/Commands/PurgeCloudflareCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

namespace App\Console\Commands;

use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;

#[Signature('cloudflare:purge-cache')]
#[Description('Purge the entire Cloudflare cache')]
class PurgeCloudflareCache extends Command
{
protected $signature = 'cloudflare:purge-cache';

protected $description = 'Purge the entire Cloudflare cache';

public function handle(): int
{
$zoneId = config('services.cloudflare.zone_id');
Expand Down
8 changes: 4 additions & 4 deletions app/Console/Commands/RemoveExternalUrlFromTextCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
namespace App\Console\Commands;

use App\Models\Post;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('blog:remove-external-url-from-text')]
#[Description('Remove the external url from the text field')]
class RemoveExternalUrlFromTextCommand extends Command
{
protected $signature = 'blog:remove-external-url-from-text';

protected $description = 'Remove the external url from the text field';

public function handle(): void
{
Post::query()->whereNotNull('external_url')->each(
Expand Down
20 changes: 10 additions & 10 deletions app/Console/Commands/ReviewPostTagsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@

use App\Models\Post;
use App\Services\TaggingService;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Prism\Prism\Exceptions\PrismRateLimitedException;
use Illuminate\Http\Client\RequestException;
use Throwable;

#[Signature('app:review-post-tags
{--dry-run : Show suggested changes without applying them}
{--post= : Review a specific post by ID}')]
#[Description('Review and update tags for all published posts using AI')]
class ReviewPostTagsCommand extends Command
{
protected $signature = 'app:review-post-tags
{--dry-run : Show suggested changes without applying them}
{--post= : Review a specific post by ID}';

protected $description = 'Review and update tags for all published posts using AI';

public function handle(TaggingService $taggingService): void
{
$query = Post::query()->published();
Expand Down Expand Up @@ -71,12 +71,12 @@ private function generateTagsWithRetry(TaggingService $taggingService, Post $pos
for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
try {
return $taggingService->generateTags($post);
} catch (PrismRateLimitedException $e) {
if ($attempt === $maxRetries) {
} catch (RequestException $e) {
if ($attempt === $maxRetries || $e->response->status() !== 429) {
throw $e;
}

$retryAfter = $e->retryAfter ?? 60;
$retryAfter = (int) ($e->response->header('Retry-After') ?? 60);
$this->warn(" Rate limited — waiting {$retryAfter}s...");
sleep($retryAfter);
}
Expand Down
4 changes: 2 additions & 2 deletions app/Console/Commands/SendTestMailCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
namespace App\Console\Commands;

use App\Mail\TestMail;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Mail;

#[Signature('send-test-mail')]
class SendTestMailCommand extends Command
{
protected $signature = 'send-test-mail';

public function handle(): void
{
Mail::to('someone-else@spatie.be')->send(new TestMail);
Expand Down
8 changes: 4 additions & 4 deletions app/Console/Commands/SyncNewsletterCampaignsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

use App\Jobs\PurgeCloudflareCacheJob;
use App\Models\NewsletterCampaign;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Spatie\MailcoachSdk\Facades\Mailcoach;
use Spatie\ResponseCache\Facades\ResponseCache;

#[Signature('newsletter:sync-campaigns')]
#[Description('Sync sent newsletter campaigns from Mailcoach')]
class SyncNewsletterCampaignsCommand extends Command
{
protected $signature = 'newsletter:sync-campaigns';

protected $description = 'Sync sent newsletter campaigns from Mailcoach';

public function handle(): void
{
$this->info('Syncing newsletter campaigns from Mailcoach...');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
namespace App\Console\Commands;

use App\Models\Post;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;

#[Signature('blog:update-external-urls-with-tweet-permalinks')]
#[Description('Update external links with tweet permalinks')]
class UpdateExternalUrlsWithTweetPermalinksCommand extends Command
{
protected $signature = 'blog:update-external-urls-with-tweet-permalinks';

protected $description = 'Update external links with tweet permalinks';

public function handle(): void
{
Post::all()
Expand Down
13 changes: 0 additions & 13 deletions app/Http/Middleware/TrimStrings.php

This file was deleted.

13 changes: 0 additions & 13 deletions app/Http/Middleware/VerifyCsrfToken.php

This file was deleted.

Loading
Loading