Completed
Push — master ( 006bd3...467982 )
by Vladimir
02:48
created

TeamFormCreator::build()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 48
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 48
rs 9.125
cc 2
eloc 28
nc 2
nop 1
1
<?php
2
/**
3
 * This file contains a form creator for Teams
4
 *
5
 * @license    https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3
6
 */
7
8
namespace BZIon\Form\Creator;
9
10
use BZIon\Form\Type\ModelType;
11
use Symfony\Component\Validator\Constraints\Image;
12
use Symfony\Component\Validator\Constraints\Length;
13
use Symfony\Component\Validator\Constraints\NotBlank;
14
15
/**
16
 * Form creator for teams
17
 */
18
class TeamFormCreator extends ModelFormCreator
19
{
20
    /**
21
     * {@inheritdoc}
22
     */
23
    protected function build($builder)
24
    {
25
        $builder->add('name', 'text', array(
26
            'constraints' => array(
27
                new NotBlank(), new Length(array(
28
                    'min' => 2,
29
                    'max' => 32, // default BZFlag motto length
30
                ))
31
            )
32
        ))->add('description', 'textarea', array(
33
            'required' => false
34
        ))->add('avatar', 'file', array(
35
            'constraints' => new Image(array(
36
                'minWidth'  => 60,
37
                'minHeight' => 60,
38
                'maxSize'   => '4M'
39
            )),
40
            'required' => false
41
        ));
42
43
        if ($this->editing) {
44
            // We are editing the team, not creating it
45
            $team = $this->editing;
46
47
            $builder->add('delete_avatar', 'submit');
48
49
            // Let the user appoint a different leader
50
            $builder->add('leader', new ModelType('Player', false, function ($query) use ($team) {
51
                // Only list players belonging in that team
52
                return $query->where('team')->is($team);
53
            }), array(
54
                'constraints' => new NotBlank()
55
            ));
56
        }
57
58
        return $builder->add('status', 'choice', array(
59
                'choices' => array(
60
                    'open'   => 'Open',
61
                    'closed' => 'Closed',
62
                ),
63
            ))
64
            ->add('submit', 'submit', [
65
                'attr' => [
66
                    'class' => 'c-button--blue pattern pattern--downward-stripes',
67
                ],
68
            ])
69
        ;
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function fill($form, $team)
76
    {
77
        $form->get('name')->setData($team->getName());
78
        $form->get('description')->setData($team->getDescription(true));
79
        $form->get('status')->setData($team->getStatus());
80
        $form->get('leader')->setData($team->getLeader());
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function enter($form)
87
    {
88
        return \Team::createTeam(
89
            $form->get('name')->getData(),
90
            $this->me->getId(),
91
            '',
92
            $form->get('description')->getData(),
93
            $form->get('status')->getData()
94
        )->setAvatarFile($form->get('avatar')->getData());
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function update($form, $team)
101
    {
102
        $team->setName($form->get('name')->getData());
103
        $team->setDescription($form->get('description')->getData());
104
        $team->setStatus($form->get('status')->getData());
105
106
        // Is the player updating the team's leader?
107
        // Don't let them do it right away - issue a confirmation notice first
108
        $leader = $form->get('leader')->getData();
109
110
        if ($leader->getId() != $team->getLeader()->getId()) {
111
            $this->controller->newLeader($leader);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Controller as the method newLeader() does only exist in the following sub-classes of Controller: TeamController. 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...
112
        }
113
114
        if ($form->get('delete_avatar')->isClicked()) {
115
            $team->resetAvatar();
116
        } else {
117
            $team->setAvatarFile($form->get('avatar')->getData());
118
        }
119
120
        return $team;
121
    }
122
}
123