Installation
composer require blackboxcode/pando-note-bundle
Add to config/bundles.php:
BlackBoxCode\PandoNoteBundle\PandoNoteBundle::class => ['all' => true],
Publish Assets
php artisan vendor:publish --provider="BlackBoxCode\PandoNoteBundle\PandoNoteBundle" --tag="config"
php artisan vendor:publish --provider="BlackBoxCode\PandoNoteBundle\PandoNoteBundle" --tag="migrations"
Run Migrations
php artisan migrate
First Use Case
Inject the PandoNoteManager service into a controller/service:
use BlackBoxCode\PandoNoteBundle\Manager\PandoNoteManager;
public function __construct(private PandoNoteManager $noteManager) {}
public function createNote(Request $request) {
$note = $this->noteManager->create([
'title' => $request->title,
'content' => $request->content,
'user_id' => auth()->id(),
]);
return response()->json($note);
}
CRUD Operations
// Create
$note = $noteManager->create(['title' => 'Test', 'content' => 'Hello']);
// Read
$notes = $noteManager->all()->where('user_id', auth()->id());
// Update
$noteManager->update($note->id, ['title' => 'Updated']);
// Delete
$noteManager->delete($note->id);
Tagging System
// Attach tags
$noteManager->attachTags($note->id, ['work', 'personal']);
// Detach tags
$noteManager->detachTags($note->id, ['work']);
// Filter by tags
$notes = $noteManager->withTags(['work']);
Rich Text Integration
Use the content field with Laravel's built-in rich text support (e.g., spatie/laravel-medialibrary for images):
$note = $noteManager->create([
'title' => 'Rich Note',
'content' => '<h1>Hello</h1><img src="/image.jpg">',
]);
Event Listeners
Subscribe to note events in EventServiceProvider:
protected $listen = [
\BlackBoxCode\PandoNoteBundle\Events\NoteCreated::class => [
\App\Listeners\LogNoteCreation::class,
],
];
API Endpoints Use Laravel's API resources to structure responses:
return new PandoNoteResource($noteManager->all());
Frontend Integration
GET /api/notes (with pagination)POST /api/notes (create)PUT /api/notes/{id} (update)note-created events).Search Functionality
Extend the Note model to add full-text search:
use Illuminate\Database\Eloquent\Builder;
public function scopeSearch(Builder $query, string $search) {
return $query->where('title', 'like', "%{$search}%")
->orWhere('content', 'like', "%{$search}%");
}
Soft Deletes
Enable soft deletes in the Note model:
use Illuminate\Database\Eloquent\SoftDeletes;
class Note extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
}
Tagging Quirks
tags table exists and is properly linked via the note_tag pivot table.$noteManager->clearTagCache($note->id);
Migration Conflicts
Performance with Large Datasets
cursor() for paginated queries:
$notes = $noteManager->all()->cursor()->paginate(20);
user_id, title, and content columns.Event Dispatching
NoteUpdated may not fire if using update() directly. Use save() instead:
$note->content = 'New content';
$note->save(); // Triggers events
Log Note Events Add a listener to log events:
public function handle(NoteCreated $event) {
\Log::info('Note created', ['note' => $event->note]);
}
Check for Missing Dependencies
Ensure doctrine/annotations and symfony/event-dispatcher are installed if using annotations or events.
Clear Cache After Config Changes
php artisan config:clear
php artisan cache:clear
Custom Fields
Extend the Note model to add custom attributes:
protected $appends = ['custom_field'];
public function getCustomFieldAttribute() {
return $this->attributes['content'] ?? null;
}
Validation Rules Override validation in a form request:
public function rules() {
return [
'title' => 'required|max:255',
'content' => 'required|min:10',
];
}
Custom Repository
Bind a custom repository in AppServiceProvider:
$this->app->bind(
\BlackBoxCode\PandoNoteBundle\Repository\NoteRepository::class,
\App\Repositories\CustomNoteRepository::class
);
API Rate Limiting
Apply rate limits to note endpoints in app/Http/Kernel.php:
'api' => [
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
'keys' => ['notes'],
'max' => 60,
],
How can I help you explore Laravel packages today?