Completed
Push — master ( e6e660...2d183f )
by Pavel
02:25
created

ColumnLink::getItemParams()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 10
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 10
loc 10
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
3
/**
4
 * @copyright   Copyright (c) 2015 Giant.cz <[email protected]>
5
 * @author      Pavel Janda <[email protected]>
6
 * @package     Giant
7
 */
8
9
namespace Ublaboo\DataGrid\Column;
10
11
use Nette\Utils\Html;
12
use Ublaboo\DataGrid\DataGrid;
13
use Ublaboo\DataGrid\Row;
14
15
class ColumnLink extends Column
16
{
17
18
	/**
19
	 * @var string
20
	 */
21
	protected $title;
22
23
	/**
24
	 * @var string
25
	 */
26
	protected $class;
27
28
	/**
29
	 * @var DataGrid
30
	 */
31
	protected $grid;
32
33
	/**
34
	 * @var array
35
	 */
36
	protected $params;
37
38
	/**
39
	 * @var string
40
	 */
41
	protected $href;
42
43
44
	/**
45
	 * @param DataGrid $grid
46
	 * @param string $column
47
	 * @param string $name
48
	 * @param string $href
49
	 * @param array $params
50
	 */
51
	public function __construct(DataGrid $grid, $column, $name, $href, $params)
52
	{
53
		parent::__construct($column, $name);
54
55
		$this->href   = $href;
56
		$this->grid   = $grid;
57
		$this->params = $params;
58
	}
59
60
61
	/**
62
	 * Render row item into template
63
	 * @param  Row   $row
64
	 * @return mixed
65
	 */
66
	public function render(Row $row)
67
	{
68
		/**
69
		 * Renderer function may be used
70
		 */
71 View Code Duplication
		if ($renderer = $this->getRenderer()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
72
			if (!$renderer->getConditionCallback()) {
73
				return call_user_func_array($renderer->getCallback(), [$row->getItem()]);
74
			}
75
76
			if (call_user_func_array($renderer->getConditionCallback(), [$row->getItem()])) {
77
				return call_user_func_array($renderer->getCallback(), [$row->getItem()]);
78
			}
79
		}
80
81
		$value = parent::render($row);
82
83
		$href = $this->grid->getPresenter()->link($this->href, $this->getItemParams($row));
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 link() does only exist in the following implementations of said interface: Nette\Application\UI\Control, Nette\Application\UI\Multiplier, Nette\Application\UI\Presenter, Nette\Application\UI\PresenterComponent, Ublaboo\DataGrid\Compone...nator\DataGridPaginator, Ublaboo\DataGrid\DataGrid.

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...
84
		$a = Html::el('a')
85
			->href($href)
86
			->setText($value);
87
88
		if ($this->title) { $a->title($this->title); }
89
		if ($this->class) { $a->class($this->class); }
90
91
		return $a;
92
	}
93
94
95
	/**
96
	 * Set attribute title
97
	 * @param string $title
98
	 */
99
	public function setTitle($title)
100
	{
101
		$this->title = $title;
102
103
		return $this;
104
	}
105
106
107
	/**
108
	 * Get attribute title
109
	 */
110
	public function getTitle()
111
	{
112
		return $this->title;
113
	}
114
115
116
	/**
117
	 * Set attribute class
118
	 * @param string $class
119
	 */
120
	public function setClass($class)
121
	{
122
		$this->class = $class;
123
124
		return $this;
125
	}
126
127
128
	/**
129
	 * Get attribute class
130
	 */
131
	public function getClass()
132
	{
133
		return $this->class;
134
	}
135
136
	/**
137
	 * Get item params (E.g. action may be called id => $item->id, name => $item->name, ...)
138
	 * @param  Row   $row
139
	 * @return array
140
	 */
141 View Code Duplication
	protected function getItemParams(Row $row)
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...
142
	{
143
		$return = [];
144
145
		foreach ($this->params as $param_name => $param) {
146
			$return[is_string($param_name) ? $param_name : $param] = $row->getValue($param);
147
		}
148
149
		return $return;
150
	}
151
152
}
153