Installation
composer require dantleech/trainer-bundle
Add to config/bundles.php:
Dantleech\TrainerBundle\TrainerBundle::class => ['all' => true],
First Use Case: Basic Activity Tracking
php bin/console trainer:activity:create Running
use Dantleech\TrainerBundle\Entity\Activity;
use Dantleech\TrainerBundle\Service\ActivityLogger;
class ActivityController extends Controller {
public function log(ActivityLogger $logger) {
$activity = new Activity();
$activity->setType('Running')
->setDuration(30) // minutes
->setDistance(5.5); // km
$logger->log($activity);
return new Response('Activity logged!');
}
}
Database Setup Run migrations:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Activity Logging
ActivityLogger service to log activities with metadata:
$logger->log($activity, [
'intensity' => 'high',
'notes' => 'Hilly terrain',
]);
Activity entity for custom fields (e.g., HeartRate, Calories).User Association
Link activities to users via UserActivity entity:
$userActivity = new UserActivity();
$userActivity->setUser($currentUser)
->setActivity($activity);
$entityManager->persist($userActivity);
API Integration Expose activities via Symfony’s serializer:
# config/packages/trainer.yaml
trainer:
api:
enabled: true
routes:
- /api/activities
Generate API endpoints automatically via bundle’s event listeners.
Reporting
Use the ActivityReportGenerator to fetch aggregated data:
$report = $reportGenerator->generate(
$user,
new \DateTime('last 7 days'),
'Running'
);
use Dantleech\TrainerBundle\Form\ActivityType;
$form = $this->createForm(ActivityType::class, $activity);
ActivityLoggedEvent for post-logging actions (e.g., notifications):
use Dantleech\TrainerBundle\Event\ActivityLoggedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ActivitySubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
ActivityLoggedEvent::NAME => 'onActivityLogged',
];
}
public function onActivityLogged(ActivityLoggedEvent $event) {
// Send email, update dashboard, etc.
}
}
Entity Mapping
User entity exists with id and email fields. Override the User entity if your schema differs:
use Dantleech\TrainerBundle\Entity\UserInterface;
class CustomUser implements UserInterface {
// Implement required methods (e.g., getId(), getEmail())
}
Migration Conflicts
Activity or UserActivity entities, run:
php bin/console doctrine:schema:update --force
Warning: This may overwrite custom fields. Backup first.Caching Reports
$cache = $this->container->get('cache.app');
$key = 'report_'.$user->getId().'_'.md5($period);
return $cache->get($key, function() use ($reportGenerator, $user, $period) {
return $reportGenerator->generate($user, $period);
});
CLI Command Scope
trainer:activity:create require a database connection. Run them in a Docker container or ensure your .env is configured.Log Activity Events
Enable debug mode and check var/log/dev.log for ActivityLoggedEvent entries:
# config/packages/monolog.yaml
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
Validate Entities Use Symfony’s validator to catch issues early:
$errors = $validator->validate($activity);
if (count($errors) > 0) {
throw new \RuntimeException((string) $errors);
}
Custom Activity Types
Extend the ActivityType entity:
namespace App\Entity;
use Dantleech\TrainerBundle\Entity\ActivityType as BaseActivityType;
class CustomActivityType extends BaseActivityType {
// Add custom fields (e.g., 'equipment_used')
}
Update the bundle’s configuration to recognize your subclass.
API Customization Override the bundle’s serializer normalizers:
# config/packages/trainer.yaml
trainer:
api:
normalizers:
- App\Serializer\CustomActivityNormalizer
Event Dispatching
Create custom events by extending ActivityLoggedEvent:
class CustomActivityEvent extends ActivityLoggedEvent {
public function __construct(Activity $activity, array $metadata, string $customField) {
parent::__construct($activity, $metadata);
$this->customField = $customField;
}
}
Dispatch manually:
$dispatcher->dispatch(new CustomActivityEvent($activity, [], 'value'));
How can I help you explore Laravel packages today?