Toolvana: production-ready media tools platform (CodeIgniter 4)

- 134-tool registry with programmatic SEO (unique titles/H1/descriptions,
  JSON-LD graphs, sitemap index, canonical 301 enforcement via required filter)
- DB-backed job queue (SKIP LOCKED) with drivers: Ffmpeg, Images (GD),
  Pdf (qpdf/gs/poppler), Youtube (thumbnails), Qr (server-side PNG)
- Security: SSRF guard, MIME validation, rate limits, API-key auth,
  bcrypt admin login, security headers
- Admin panel: dashboard, tools/categories/guides CRUD, SEO audit,
  analytics, job inspector with retry, system health, feature flags
- Docker deployment (nginx + web/api FPM pools + scalable workers),
  PHPUnit suite (19 tests / 1139 assertions), PWA manifest + service worker
This commit is contained in:
deepseek
2026-08-23 07:10:30 +00:00
commit beaf0e1f37
217 changed files with 19619 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
<?php
declare(strict_types=1);
namespace App\Controllers;
/**
* Tool directory: /tools with search, category filter, popular, recent
* and AZ views. Server-rendered links only — crawlable navigation.
*/
final class Directory extends BaseController
{
public function index(): string
{
$finder = service('finder');
$q = trim((string) $this->request->getGet('q'));
$cat = (string) ($this->request->getGet('category') ?? '');
$tools = $finder->all();
if ($q !== '') {
$tools = service('toolSearch')->find($q, 100);
service('analytics')->track('search', ['meta' => ['term' => mb_substr($q, 0, 80), 'scope' => 'directory']]);
}
if ($cat !== '') {
$tools = array_values(array_filter(
$tools,
static fn (array $t): bool => (service('finder')->categoryById((int) $t['category_id'])['slug'] ?? '') === $cat
));
}
$this->seo->title('All Tools ' . config('Site')->name)
->description('Search and browse every free online tool: video, audio, image, GIF, PDF and YouTube utilities.')
->canonical('/tools')
->breadcrumbs([['label' => 'Tools']]);
return $this->render('directory', [
'tools' => $tools,
'categories' => $finder->categories(),
'query' => $q,
'activeCat' => $cat,
'view' => 'all-tools',
]);
}
public function popular(): string
{
return $this->renderList(
'Popular Tools',
'The most used tools across the platform right now.',
service('finder')->popular(24),
'/tools/popular'
);
}
public function recent(): string
{
return $this->renderList(
'Recently Added Tools',
'Fresh additions to the toolbox.',
service('finder')->recent(24),
'/tools/recent'
);
}
public function az(): string
{
return $this->renderList(
'All Tools AZ',
'Every tool in alphabetical order.',
service('finder')->all(),
'/tools/a-z'
);
}
public function category(string $slug): string
{
return redirect()->to('/' . $slug, 301);
}
private function renderList(string $h1, string $intro, array $tools, string $path): string
{
$this->seo->title($h1 . ' ' . config('Site')->name)
->description(mb_substr($intro, 0, 300))
->canonical($path)
->breadcrumbs([['label' => 'Tools', 'url' => '/tools'], ['label' => $h1]]);
return $this->render('directory_list', [
'tools' => $tools,
'h1' => $h1,
'intro' => $intro,
'view' => $path,
]);
}
}