Completed
Push — master ( b13aa8...0a3a64 )
by Julien
11:57
created

PlayOffTreeGen::getNumRounds()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Xoco70\KendoTournaments\TreeGen;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Support\Facades\App;
7
use Xoco70\KendoTournaments\Models\Championship;
8
use Xoco70\KendoTournaments\Models\DirectEliminationFight;
9
use Xoco70\KendoTournaments\Models\Fight;
10
use Xoco70\KendoTournaments\Models\PreliminaryFight;
11
12
class PlayOffTreeGen extends TreeGen
13
{
14
15
16
    /**
17
     * Calculate the Byes need to fill the Championship Tree.
18
     * @param Championship $championship
0 ignored issues
show
Bug introduced by
There is no parameter named $championship. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
19
     * @param $fighters
20
     * @return Collection
21
     */
22
    protected function getByeGroup($fighters)
23
    {
24
        $fighterCount = $fighters->count();
25
        $preliminaryGroupSize = $this->championship->getSettings()->preliminaryGroupSize;
26
        $treeSize = $this->getTreeSize($fighterCount, $preliminaryGroupSize);
27
        $byeCount = $treeSize - $fighterCount;
28
29
        return $this->createNullsGroup($byeCount);
30
    }
31
32
    /**
33
     * Save Groups with their parent info
34
     * @param integer $numRounds
35
     * @param $numFightersElim
36
     */
37 View Code Duplication
    protected function pushGroups($numRounds, $numFightersElim)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
    {
39
        // TODO Here is where you should change when enable several winners for preliminary
40
        for ($roundNumber = 2; $roundNumber <= $numRounds +1; $roundNumber++) {
41
            // From last match to first match
42
            $maxMatches = ($numFightersElim / pow(2, $roundNumber));
43
44
            for ($matchNumber = 1; $matchNumber <= $maxMatches; $matchNumber++) {
45
                $fighters = $this->createByeGroup(2);
46
                $group = $this->saveGroup(1, $matchNumber, $roundNumber, null);
47
                $this->syncGroup($group, $fighters);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Xoco70\KendoTournaments\TreeGen\PlayOffTreeGen as the method syncGroup() does only exist in the following sub-classes of Xoco70\KendoTournaments\TreeGen\PlayOffTreeGen: Xoco70\KendoTournaments\...layOffCompetitorTreeGen, Xoco70\KendoTournaments\TreeGen\PlayOffTeamTreeGen. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
48
            }
49
        }
50
    }
51
    /**
52
     * Create empty groups for direct Elimination Tree
53
     * @param $numFighters
54
     */
55
    public function pushEmptyGroupsToTree($numFighters)
56
    {
57
        $numFightersElim = $numFighters / $this->championship->getSettings()->preliminaryGroupSize * 2;
58
        // We calculate how much rounds we will have
59
        $numRounds = intval(log($numFightersElim, 2)) ; // 3 rounds, but begining from round 2 ( ie => 4)
60
        $this->pushGroups($numRounds, $numFightersElim);
61
    }
62
63
    /**
64
     * Chunk Fighters into groups for fighting, and optionnaly shuffle
65
     * @param $round
66
     * @param $fightersByEntity
67
     * @return mixed
68
     */
69
    protected function chunkAndShuffle($round, $fightersByEntity)
0 ignored issues
show
Unused Code introduced by
The parameter $round is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
    {
71
        if ($this->championship->hasPreliminary()) {
72
            $fightersGroup = $fightersByEntity->chunk($this->settings->preliminaryGroupSize);
73
            if (!App::runningUnitTests()) {
74
                $fightersGroup = $fightersGroup->shuffle();
75
            }
76
        } else { // Round Robin
77
            $fightersGroup = $fightersByEntity->chunk($fightersByEntity->count());
78
        }
79
        return $fightersGroup;
80
    }
81
82
    /**
83
     * Generate First Round Fights
84
     */
85
    public function generateFights()
86
    {
87
        //  First Round Fights
88
        $settings = $this->championship->getSettings();
89
        parent::destroyPreviousFights();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (destroyPreviousFights() instead of generateFights()). Are you sure this is correct? If so, you might want to change this to $this->destroyPreviousFights().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
90
        $groups = $this->championship->groupsByRound(1)->get();
91
        // Very specific case to common case : Preliminary with 3 fighters
92
        if ($settings->preliminaryGroupSize == 3) {
93
            for ($numFight = 1; $numFight <= $settings->preliminaryGroupSize; $numFight++) {
94
                $fight = new PreliminaryFight;
95
                $fight->saveFights($groups, $numFight);
96
            }
97
        }
98
    }
99
100
101
    /**
102
     * Generate Fights for next rounds
103
     */
104
    public function generateNextRoundsFights()
105
    {
106
        $fight = new DirectEliminationFight;
107
        $fight->saveFights($this->championship,2);
108
    }
109
110
    /**
111
     * Return number of rounds for the tree based on fighter count
112
     * @param $numFighters
113
     * @return int
114
     */
115
    public function getNumRounds($numFighters){
116
        return intval(log($numFighters / $this->championship->getSettings()->preliminaryGroupSize * 2, 2));
117
    }
118
}
119