Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Elo Bundle Laravel Package

avoo/elo-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require avoo/elo-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

    return [
        // ...
        Avoo\EloBundle\AvooEloBundle::class,
        Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class,
    ];
    
  2. Configure Doctrine (config/packages/doctrine.yaml or config.yml):

    doctrine:
        orm:
            mappings:
                gedmo_loggable: ~
    
  3. Create Entities: Extend the base classes (EloPlayer, EloVersus) and implement EloUserInterface in your User entity.

  4. First Use Case: Calculate Elo ratings after a match:

    $match = $entityManager->getRepository(EloVersus::class)->find($matchId);
    $calculator = $this->get('avoo_elo.calculator');
    $calculator->calculate($match);
    $aggregation = $calculator->getAggregation(); // Updated ratings
    

Implementation Patterns

Core Workflow

  1. Match Creation:

    $versus = new EloVersus();
    $versus->setPlayerA($playerA);
    $versus->setPlayerB($playerB);
    $versus->setResultA(true); // Winner
    $entityManager->persist($versus);
    $entityManager->flush();
    
  2. Batch Processing: Use Doctrine’s BATCH_SIZE or queue workers (e.g., Symfony Messenger) to process multiple matches:

    $matches = $entityManager->getRepository(EloVersus::class)->findBy(['processed' => false], null, 50);
    foreach ($matches as $match) {
        $calculator->calculate($match);
        $match->setProcessed(true);
    }
    $entityManager->flush();
    
  3. Integration with Events: Trigger Elo recalculations post-match via Doctrine lifecycle events:

    // src/EventListener/EloListener.php
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getObject();
        if ($entity instanceof EloVersus && !$entity->isProcessed()) {
            $calculator = $this->container->get('avoo_elo.calculator');
            $calculator->calculate($entity);
        }
    }
    
  4. Custom Aggregation: Extend the default aggregation logic (e.g., weighted averages for tournaments):

    $calculator->setAggregationStrategy(new CustomEloAggregation());
    

Gotchas and Tips

Pitfalls

  1. Missing Dependencies: Ensure stof/doctrine-extensions-bundle is installed (required for EloPlayer/EloVersus entities).

  2. Circular References: Avoid bidirectional associations without proper cascade settings. Example:

    // EloPlayer.php
    @ORM\OneToOne(targetEntity="AppBundle\Entity\User", inversedBy="eloPlayer", cascade={"persist"})
    
  3. Race Conditions: Use database transactions or optimistic locking (@ORM\Version) when updating Elo ratings concurrently.

  4. Initial Elo Values: The bundle assumes initial Elo values are set in EloPlayer. Default to 1200 (standard chess rating) or fetch from a config:

    # config/packages/avoo_elo.yaml
    avoo_elo:
        default_elo: 1500
    

Debugging

  • Verify Calculations: Log raw inputs/outputs of EloPoint calculations for validation:

    $calculator->calculate($match);
    $this->logger->info('Elo Update', [
        'playerA' => $match->getPlayerA()->getElo(),
        'playerB' => $match->getPlayerB()->getElo(),
        'result' => $match->getResultA(),
    ]);
    
  • Check Entity States: Use Doctrine’s getChanges() to debug unsaved Elo updates:

    $player = $entityManager->getRepository(EloPlayer::class)->find($id);
    $changes = $entityManager->getUnitOfWork()->getEntityChangeSet($player);
    

Extension Points

  1. Custom K-Factor: Override the default K=32 (for chess) in your EloPoint service:

    services:
        avoo_elo.calculator:
            arguments:
                $kFactor: 20 # Lower for stable ratings
    
  2. Additional Match Metadata: Extend EloVersus to store match context (e.g., tournamentId, surfaceType):

    /**
     * @ORM\Column(type="string", nullable=true)
     */
    private $surface;
    
  3. Asynchronous Processing: Use Symfony’s Messenger to decouple Elo calculations from match creation:

    $message = new CalculateEloMessage($matchId);
    $this->messageBus->dispatch($message);
    
  4. API Integration: Expose Elo ratings via API with serializers:

    // src/Serializer/EloPlayerNormalizer.php
    public function normalize($eloPlayer, $format = null, array $context = [])
    {
        return [
            'id' => $eloPlayer->getId(),
            'elo' => $eloPlayer->getElo(),
            'rank' => $eloPlayer->getRank(), // Custom method
        ];
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle