Issues (2)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Columnized.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Yii2 Columnized.
4
 *
5
 * This file contains Columnized widget.
6
 *
7
 * @author  Aleksei Korotin <[email protected]>
8
 */
9
10
namespace herroffizier\yii2columnized;
11
12
use yii\helpers\Html;
13
use yii\base\Widget;
14
use yii\helpers\ArrayHelper;
15
use yii\base\InvalidConfigException;
16
17
class Columnized extends Widget
18
{
19
    /**
20
     * Data source.
21
     *
22
     * @var \yii\data\DataProviderInterface
23
     */
24
    public $dataProvider;
25
26
    /**
27
     * Amount of columns.
28
     *
29
     * @var int
30
     */
31
    public $columns = 4;
32
33
    /**
34
     * Zero-based array of hardcoded column sizes.
35
     *
36
     * Note that last column will include all left items.
37
     *
38
     * @var int[]
39
     */
40
    public $columnSizes = [];
41
42
    /**
43
     * View file for container.
44
     *
45
     * If used, you should print $content in your view.
46
     *
47
     * If omitted, container will be generated automatically.
48
     *
49
     * @var string
50
     */
51
    public $containerView;
52
53
    /**
54
     * Options for autogenerated container.
55
     *
56
     * Use 'tag' option to change container's tag (div by default).
57
     *
58
     * @var array
59
     */
60
    public $containerOptions = [];
61
62
    /**
63
     * View file for column.
64
     *
65
     * If used, you should print $content in your view.
66
     *
67
     * If omitted, column will be generated automatically.
68
     *
69
     * @var string
70
     */
71
    public $columnView;
72
73
    /**
74
     * Options for autogenerated column.
75
     *
76
     * Use 'tag' option to change column's tag (div by default).
77
     *
78
     * @var array
79
     */
80
    public $columnOptions = [];
81
82
    /**
83
     * View file for item.
84
     *
85
     * Required.
86
     *
87
     * Model is passed in $model variable.
88
     *
89
     * @var string.
90
     */
91
    public $itemView;
92
93
    /**
94
     * Get items from data provider.
95
     *
96
     * @return array
97
     */
98 90
    protected function getItems()
99
    {
100 90
        return $this->dataProvider->getModels();
101
    }
102
103
    /**
104
     * Get item count for specified column.
105
     *
106
     * @param int $itemCount
107
     * @param int $columns
108
     * @param int $columnIndex
109
     *
110
     * @return int
111
     */
112 90
    protected function getItemsPerColumn($itemCount, $columnCount, $columnIndex)
113
    {
114
        return (int) (
115 90
            isset($this->columnSizes[$columnIndex])
116 66
                ? $this->columnSizes[$columnIndex]
117 90
                : ceil($itemCount / $columnCount)
118 60
            );
119
    }
120
121
    /**
122
     * Render wrapper block.
123
     *
124
     * If $view is not null, $view file will be rendered with $content and $widget variables
125
     * passed to it.
126
     * Ir $view is null, wrapper will be generated with $options array.
127
     *
128
     * Used by renderContainer and renderColumn.
129
     *
130
     * @param string|null $view
131
     * @param array       $options
132
     * @param string      $content
133
     * @param array       $viewOptions
134
     */
135 90
    protected function renderWrapper($view, array $options, $content, array $viewOptions)
136
    {
137 90
        if ($view) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $view of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
138 69
            echo $this->render($view, array_merge($viewOptions, ['content' => $content, 'widget' => $this]));
139 46
        } else {
140 51
            $tag = ArrayHelper::getValue($options, 'tag', 'div');
141 51
            unset($options['tag']);
142
143 51
            echo Html::tag($tag, $content, $options);
144
        }
145 90
    }
146
147
    /**
148
     * Render item.
149
     *
150
     * @param mixed $item
151
     */
152 75
    protected function renderItem($item)
153
    {
154 75
        echo $this->render($this->itemView, ['model' => $item, 'widget' => $this]);
155 75
    }
156
157
    /**
158
     * Render column.
159
     *
160
     * @param string $itemsContent
161
     * @param int    $columnIndex
162
     * @param int    $itemsInColumn
163
     */
164 75
    protected function renderColumn($itemsContent, $columnIndex, $itemsInColumn)
165
    {
166 75
        $this->renderWrapper(
167 75
            $this->columnView,
168 75
            $this->columnOptions,
169 50
            $itemsContent,
170 75
            ['columnIndex' => $columnIndex, 'itemsInColumn' => $itemsInColumn]
171 50
        );
172 75
    }
173
174
    /**
175
     * Begin new column.
176
     *
177
     * This method start output buffering.
178
     */
179 75
    protected function beginColumn()
180
    {
181 75
        ob_start();
182 75
    }
183
184
    /**
185
     * End current column.
186
     *
187
     * This method stops output buffering and renders column.
188
     *
189
     * @param int $columnIndex
190
     * @param int $itemsInColumn
191
     */
192 75
    protected function endColumn($columnIndex, $itemsInColumn)
193
    {
194 75
        $itemsContent = ob_get_clean();
195 75
        $this->renderColumn($itemsContent, $columnIndex, $itemsInColumn);
196 75
    }
197
198
    /**
199
     * Render container.
200
     *
201
     * @param string $columnsContent
202
     * @param int    $columnCount
203
     * @param int    $itemCount
204
     */
205 90
    protected function renderContainer($columnsContent, $columnCount, $itemCount)
206
    {
207 90
        $this->renderWrapper(
208 90
            $this->containerView,
209 60
            array_merge(
210 90
                $this->containerOptions,
211 90
                ['id' => $this->getId()]
212 60
            ),
213 60
            $columnsContent,
214 90
            ['columnCount' => $columnCount, 'itemCount' => $itemCount]
215 60
        );
216 90
    }
217
218
    /**
219
     * Begin container.
220
     *
221
     * This method start output buffering.
222
     */
223 90
    protected function beginContainer()
224
    {
225 90
        ob_start();
226 90
    }
227
228
    /**
229
     * End container.
230
     *
231
     * This method stops output buffering and renders container.
232
     *
233
     * @param int $columnCount
234
     * @param int $itemCount
235
     */
236 90
    protected function endContainer($columnCount, $itemCount)
237
    {
238 90
        $columnsContent = ob_get_clean();
239 90
        $this->renderContainer($columnsContent, $columnCount, $itemCount);
240 90
    }
241
242 99
    public function run()
243
    {
244 99
        if (!$this->dataProvider) {
245 6
            throw new InvalidConfigException('dataProvider parameter is required');
246
        }
247
248 93
        if (!$this->itemView) {
249 3
            throw new InvalidConfigException('itemView parameter is required');
250
        }
251
252 90
        $items = $this->getItems();
253 90
        $itemCount = count($items);
254 90
        $itemsPerColumn = $this->getItemsPerColumn($itemCount, $this->columns, 0);
255
256 90
        $this->beginContainer();
257
258 90
        $itemsInColumn = 0;
259 90
        $columnIndex = 0;
260 90
        foreach ($items as $item) {
261 75
            ++$itemsInColumn;
262
263 75
            if ($itemsInColumn === 1) {
264 75
                $this->beginColumn();
265 50
            }
266
267 75
            $this->renderItem($item);
268
269 75
            if ($itemsInColumn === $itemsPerColumn && ($columnIndex + 1 < $this->columns)) {
270 75
                $this->endColumn($columnIndex, $itemsInColumn);
271
272 75
                ++$columnIndex;
273 75
                $itemsInColumn = 0;
274 75
                $itemsPerColumn = $this->getItemsPerColumn($itemCount, $this->columns, $columnIndex);
275 50
            }
276 60
        }
277
278 90
        if ($itemsInColumn !== 0) {
279 33
            $this->endColumn($columnIndex, $itemsInColumn);
280
281 33
            ++$columnIndex;
282 22
        }
283
284 90
        $this->endContainer($columnIndex, $itemCount);
285 90
    }
286
}
287