<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }
<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }<?php namespace App\Command; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; #[AsCommand( name: 'app:rebuild-source-code-cache', description: 'Rebuild the cached source code used for the background animation.' )] final class RebuildSourceCodeCacheCommand extends Command { public function __construct( private readonly CacheItemPoolInterface $cache ) { parent::__construct(); } protected function execute(InputInterface $input, OutputInterface $output): int { $cacheItem = $this->cache->getItem('twig_globals'); $cacheItem->set([ 'source_code' => SourceCodeReader::getAllSourceCode(), ]); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); $output->writeln('<info>Source code cache rebuilt.</info>'); return Command::SUCCESS; } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class WakaTimeController extends AbstractController { #[Route('/api/wakatime/last-7-days', name: 'app_wakatime_last_7_days', methods: ['GET'])] public function last7Days(): JsonResponse { $apiKey = $_ENV['WAKATIME_API_KEY'] ?? ''; if ($apiKey === '') { return new JsonResponse( ['error' => 'WAKATIME_API_KEY missing'], Response::HTTP_SERVICE_UNAVAILABLE ); } $url = sprintf( 'https://wakatime.com/api/v1/users/current/stats/last_7_days?api_key=%s', rawurlencode($apiKey) ); $statusCode = Response::HTTP_OK; $body = null; if (function_exists('curl_init')) { $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 8, ]); $body = curl_exec($ch); $statusCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); } else { $body = @file_get_contents($url); if (isset($http_response_header[0]) && preg_match('/\s(\d{3})\s/', $http_response_header[0], $matches)) { $statusCode = (int) $matches[1]; } } $payload = $body ? json_decode($body, true) : null; if (!is_array($payload)) { return new JsonResponse( ['error' => 'WakaTime request failed'], Response::HTTP_BAD_GATEWAY ); } $data = $payload['data'] ?? []; $languages = array_slice($data['languages'] ?? [], 0, 3); $languages = array_map( static fn (array $lang) => [ 'name' => $lang['name'] ?? '', 'percent' => $lang['percent'] ?? 0, ], $languages ); $response = [ 'total' => $data['human_readable_total'] ?? '', 'daily_average' => $data['human_readable_daily_average'] ?? '', 'best_day' => [ 'date' => $data['best_day']['date'] ?? '', 'text' => $data['best_day']['text'] ?? '', ], 'languages' => $languages, ]; return new JsonResponse( $response, $statusCode ?: Response::HTTP_OK, ['Vary' => 'Accept'] ); } }
<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }<?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; final class IndexController extends AbstractController { #[Route('/', name: 'app_index')] public function index(): Response { $manifestPath = $this->getParameter('kernel.project_dir') . '/public/frontend/.vite/manifest.json'; $vite = [ 'is_dev_server' => !file_exists($manifestPath), 'js' => null, 'css' => [], ]; if (!$vite['is_dev_server']) { $manifest = json_decode((string) file_get_contents($manifestPath), true); $entry = $manifest['src/main.js'] ?? $manifest['index.html'] ?? null; if (!$entry) { foreach ($manifest as $item) { if (!empty($item['isEntry'])) { $entry = $item; break; } } } if ($entry) { $vite['js'] = $entry['file'] ?? null; $vite['css'] = $entry['css'] ?? []; } } return $this->render('index/index.html.twig', [ 'vite' => $vite, ]); } }
<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }<?php namespace App\Service; use Symfony\Component\Finder\Finder; class SourceCodeReader { public static function getAllSourceCode(): string { $finder = new Finder(); $finder->files()->in(__DIR__ . '/../')->name('*.php'); $sourceCode = []; foreach ($finder as $file) { $contents = file_get_contents($file->getRealPath()); $length = strlen(preg_replace('~[\r\n]+~', ' ', trim($contents))); $sourceCode[] = str_repeat(preg_replace('~[\r\n]+~', ' ', trim($contents)),abs(3000/ $length)); } while(count($sourceCode)<200){ array_push($sourceCode, ...$sourceCode); } return implode("\n", $sourceCode); } }
<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }<?php namespace App\Dto\WakaTime; final class BestDay { public function __construct( public readonly ?string $date, public readonly ?string $text, public readonly ?int $totalSeconds ) { } public static function fromApi(array $data): self { return new self( $data['date'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null ); } }
<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }<?php namespace App\Dto\WakaTime; final class Last7DaysResponse { public function __construct( public readonly ?Last7DaysData $data, public readonly ?string $start, public readonly ?string $end, public readonly ?string $range, public readonly ?string $timezone, public readonly ?string $userId ) { } public static function fromApi(array $payload): self { $data = isset($payload['data']) && is_array($payload['data']) ? Last7DaysData::fromApi($payload['data']) : null; return new self( $data, $payload['start'] ?? null, $payload['end'] ?? null, $payload['range'] ?? null, $payload['timezone'] ?? null, $payload['user_id'] ?? null ); } }
<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }<?php namespace App\Dto\WakaTime; final class WakaTimeStatItem { public function __construct( public readonly ?string $name, public readonly ?string $text, public readonly ?int $totalSeconds, public readonly ?float $percent, public readonly ?int $hours, public readonly ?int $minutes ) { } public static function fromApi(array $data): self { return new self( $data['name'] ?? null, $data['text'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['percent']) ? (float) $data['percent'] : null, isset($data['hours']) ? (int) $data['hours'] : null, isset($data['minutes']) ? (int) $data['minutes'] : null ); } public static function map(array $items): array { if (!is_array($items)) { return []; } $mapped = []; foreach ($items as $item) { if (is_array($item)) { $mapped[] = self::fromApi($item); } } return $mapped; } }
<?php namespace App\Dto\WakaTime; final class Last7DaysData { public function __construct( public readonly ?string $humanReadableTotal, public readonly ?string $humanReadableDailyAverage, public readonly ?string $humanReadableTotalIncludingOtherLanguage, public readonly ?string $humanReadableDailyAverageIncludingOtherLanguage, public readonly ?int $totalSeconds, public readonly ?float $dailyAverage, public readonly ?float $dailyAverageIncludingOtherLanguage, public readonly ?BestDay $bestDay, public readonly array $languages, public readonly array $editors, public readonly array $operatingSystems, public readonly array $projects, public readonly array $categories, public readonly array $branches, public readonly array $entities, public readonly array $machines, public readonly array $dependencies ) { } public static function fromApi(array $data): self { return new self( $data['human_readable_total'] ?? null, $data['human_readable_daily_average'] ?? null, $data['human_readable_total_including_other_language'] ?? null, $data['human_readable_daily_average_including_other_language'] ?? null, isset($data['total_seconds']) ? (int) $data['total_seconds'] : null, isset($data['daily_average']) ? (float) $data['daily_average'] : null, isset($data['daily_average_including_other_language']) ? (float) $data['daily_average_including_other_language'] : null, isset($data['best_day']) && is_array($data['best_day']) ? BestDay::fromApi($data['best_day']) : null, WakaTimeStatItem::map($data['languages'] ?? []), WakaTimeStatItem::map($data['editors'] ?? []), WakaTimeStatItem::map($data['operating_systems'] ?? []), WakaTimeStatItem::map($data['projects'] ?? []), WakaTimeStatItem::map($data['categories'] ?? []), WakaTimeStatItem::map($data['branches'] ?? []), WakaTimeStatItem::map($data['entities'] ?? []), WakaTimeStatItem::map($data['machines'] ?? []), WakaTimeStatItem::map($data['dependencies'] ?? []) ); } }
<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }<?php namespace App\Twig\Extension; use App\Service\SourceCodeReader; use Psr\Cache\CacheItemPoolInterface; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; class CachedGlobalsExtension extends AbstractExtension implements GlobalsInterface { public function __construct( private CacheItemPoolInterface $cache ) {} public function getGlobals(): array { $cacheItem = $this->cache->getItem('twig_globals'); if (!$cacheItem->isHit()) { $globals = [ 'source_code' => SourceCodeReader::getAllSourceCode(), ]; $cacheItem->set($globals); $cacheItem->expiresAfter(86400); $this->cache->save($cacheItem); } else { $globals = $cacheItem->get(); } return $globals; } }
<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }<?php namespace App\Twig\Runtime; use Twig\Extension\RuntimeExtensionInterface; class CachedGlobalsExtensionRuntime implements RuntimeExtensionInterface { public function __construct() { } public function doSomething($value) { } }
<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }<?php namespace App; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\HttpKernel\Kernel as BaseKernel; class Kernel extends BaseKernel { use MicroKernelTrait; }