Completed
Push — master ( 118c60...254398 )
by Litera
03:47
created

ProgramForm::createComponentProgramForm()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 37
nc 1
nop 0
dl 0
loc 45
ccs 0
cts 36
cp 0
crap 2
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace App\Components\Forms;
4
5
use App\Models\MeetingModel;
6
use App\Repositories\BlockRepository;
7
use App\Repositories\CategoryRepository;
8
use Nette\Application\UI\Form;
9
use Nette\Database\Table\ActiveRow;
10
use Nette\Forms\Controls\SubmitButton;
11
12 1
class ProgramForm extends BaseForm
13
{
14
15
	const TEMPLATE_NAME = 'ProgramForm';
16
17
	const MESSAGE_REQUIRED = 'Hodnota musí být vyplněna!';
18
	const MESSAGE_MAX_LENGTH = '%label nesmí mít více jak %d znaků!';
19
20
	/**
21
	 * @var Closure
22
	 */
23
	public $onProgramSave;
24
25
	/**
26
	 * @var Closure
27
	 */
28
	public $onProgramReset;
29
30
	/**
31
	 * @var BlockRepository
32
	 */
33
	protected $blockRepository;
34
35
	/**
36
	 * @var CategoryRepository
37
	 */
38
	protected $categoryRepository;
39
40
	/**
41
	 * @param BlockRepository    $blockRepository
42
	 * @param CategoryRepository $categoryRepository
43
	 */
44
	public function __construct(
45
		BlockRepository $blockRepository,
46
		CategoryRepository $categoryRepository
47
	) {
48 1
		$this->setBlockRepository($blockRepository);
49 1
		$this->setCategoryRepository($categoryRepository);
50 1
	}
51
52
	/**
53
	 * @return void
54
	 */
55
	public function render()
56
	{
57
		$template = $this->getTemplate();
58
		$template->setFile($this->buildTemplatePath());
59
		$template->backlink = 'Program:listing';
0 ignored issues
show
Bug introduced
Accessing backlink on the interface Nette\Application\UI\ITemplate suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
60
		$template->render();
61
	}
62
63
	/**
64
	 * @param  array $defaults
65
	 * @return AnnotationForm
66
	 */
67
	public function setDefaults(ActiveRow $defaults): ProgramForm
68
	{
69
		$this['programForm']->setDefaults($defaults);
70
71
		return $this;
72
	}
73
74
	/**
75
	 * @return Form
76
	 */
77
	public function createComponentProgramForm(): Form
78
	{
79
		$form = new Form;
80
81
		$form->addText('name', 'Název:')
82
			->setRequired(static::MESSAGE_REQUIRED)
0 ignored issues
show
Documentation introduced
static::MESSAGE_REQUIRED is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
83
			->addRule(Form::MAX_LENGTH, static::MESSAGE_MAX_LENGTH, 50)
84
			->setAttribute('size', 50)
0 ignored issues
show
Documentation introduced
50 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
85
			->getLabelPrototype()->setAttribute('class', 'required');
86
		$form->addTextArea('description', 'Popis:')
87
			->setAttribute('rows', 10)
0 ignored issues
show
Documentation introduced
10 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
88
			->setAttribute('cols', 80);
0 ignored issues
show
Documentation introduced
80 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
89
		$form->addTextArea('material', 'Materiál:')
90
			->setAttribute('rows', 2)
0 ignored issues
show
Documentation introduced
2 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
91
			->setAttribute('cols', 80);
0 ignored issues
show
Documentation introduced
80 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
		$form->addText('tutor', 'Lektor:')
93
			->setAttribute('size', 30);
0 ignored issues
show
Documentation introduced
30 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
94
		$form->addText('email', 'E-mail:')
95
			->setAttribute('size', 30);
0 ignored issues
show
Documentation introduced
30 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
96
		$form->addText('capacity', 'Kapacita:')
97
			->setDefaultValue(0)
98
			->setAttribute('size', 10)
0 ignored issues
show
Documentation introduced
10 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
99
			->setAttribute('placeholder', 0);
0 ignored issues
show
Documentation introduced
0 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
100
		$form->addRadioList('display_in_reg', 'Zobrazit v registraci:', [1 => 'Ano', 0 => 'Ne'])
101
			->getSeparatorPrototype()->setName(null);
102
		$form->addSelect('block', 'Blok:', $this->buildBlockSelect());
103
		$form->addSelect('category', 'Kategorie:', $this->buildCategorySelect());
104
105
		$form->addHidden('id');
106
		$form->addHidden('guid');
107
		$form->addHidden('backlink');
108
109
		$form->addSubmit('save', 'Uložit')
110
			->setAttribute('class', 'btn-primary')
0 ignored issues
show
Documentation introduced by
'btn-primary' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111
			->onClick[] = [$this, 'processForm'];
112
		$form->addSubmit('reset', 'Storno')
113
			->setAttribute('class', 'btn-reset')
0 ignored issues
show
Documentation introduced by
'btn-reset' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
114
			->onClick[] = [$this, 'processReset'];
115
116
		$form->setDefaults(['display_in_reg' => 1]);
117
118
		$form = $this->setupRendering($form);
119
120
		return $form;
121
	}
122
123
	/**
124
	 * @param  SubmitButton $button
125
	 * @return void
126
	 */
127
	public function processForm(SubmitButton $button)
128
	{
129
		$program = $button->getForm()->getValues();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Nette\ComponentModel\IComponent as the method getValues() does only exist in the following implementations of said interface: Nette\Application\UI\Form, Nette\Forms\Container, Nette\Forms\Form.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
130
131
		$this->onProgramSave($this, $program);
0 ignored issues
show
Documentation Bug introduced
The method onProgramSave does not exist on object<App\Components\Forms\ProgramForm>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
132
	}
133
134
	/**
135
	 * @param  SubmitButton $button
136
	 * @return void
137
	 */
138
	public function processReset(SubmitButton $button)
139
	{
140
		$program = $button->getForm()->getValues();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Nette\ComponentModel\IComponent as the method getValues() does only exist in the following implementations of said interface: Nette\Application\UI\Form, Nette\Forms\Container, Nette\Forms\Form.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
141
142
		$this->onProgramReset($this, $program);
0 ignored issues
show
Documentation Bug introduced by
The method onProgramReset does not exist on object<App\Components\Forms\ProgramForm>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
143
	}
144
145
	/**
146
	 * @return array
147
	 */
148
	protected function buildBlockSelect(): array
149
	{
150 1
		$blocks = $this->getBlockRepository()->findByMeeting($this->getMeetingId());
151
152 1
		$selectContent = [];
153
154 1
		foreach($blocks as $block) {
155 1
			$selectContent[$block->id] = sprintf(
156 1
				'%s, %s - %s : %s',
157 1
				$block->day,
158 1
				$block->from->format('%H:%I:%S'),
159 1
				$block->to->format('%H:%I:%S'),
160 1
				$block->name
161
			);
162
		}
163
164 1
		return $selectContent;
165
	}
166
167
	/**
168
	 * @return array
169
	 */
170
	protected function buildCategorySelect(): array
171
	{
172 1
		$categories = $this->getCategoryRepository()->findAll();
173
174 1
		$selectContent = [];
175
176 1
		foreach($categories as $category) {
177 1
			$selectContent[$category->id] = $category->name;
178
		}
179
180 1
		return $selectContent;
181
	}
182
183
	/**
184
	 * @return BlockRepository
185
	 */
186
	public function getBlockRepository(): BlockRepository
187
	{
188 1
		return $this->blockRepository;
189
	}
190
191
	/**
192
	 * @param BlockRepository $blockRepository
0 ignored issues
show
Documentation introduced
There is no parameter named $blockRepository. Did you maybe mean $repository?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
193
	 *
194
	 * @return self
195
	 */
196
	public function setBlockRepository(BlockRepository $repository): self
197
	{
198 1
		$this->blockRepository = $repository;
199
200 1
		return $this;
201
	}
202
203
	/**
204
	 * @return CategoryRepository
205
	 */
206
	public function getCategoryRepository(): CategoryRepository
207
	{
208 1
		return $this->categoryRepository;
209
	}
210
211
	/**
212
	 * @param CategoryRepository $categoryRepository
0 ignored issues
show
Documentation introduced
There is no parameter named $categoryRepository. Did you maybe mean $repository?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
213
	 *
214
	 * @return self
215
	 */
216
	public function setCategoryRepository(CategoryRepository $repository): self
217
	{
218 1
		$this->categoryRepository = $repository;
219
220 1
		return $this;
221
	}
222
}
223