View::getIterator()   C
last analyzed

Complexity

Conditions 8
Paths 10

Size

Total Lines 41
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

Changes 3
Bugs 0 Features 0
Metric Value
dl 0
loc 41
ccs 23
cts 23
cp 1
rs 5.3846
c 3
b 0
f 0
cc 8
eloc 24
nc 10
nop 0
crap 8
1
<?php
2
/**
3
 * AnimeDb package.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/GPL-3.0 GPL v3
8
 */
9
namespace AnimeDb\Bundle\AppBundle\Util\Pagination;
10
11
use Doctrine\Common\Collections\ArrayCollection;
12
13
class View implements \IteratorAggregate
14
{
15
    /**
16
     * @var Configuration
17
     */
18
    protected $config;
19
20
    /**
21
     * @var Node|null
22
     */
23
    protected $first = null;
24
25
    /**
26
     * @var Node|null
27
     */
28
    protected $prev = null;
29
30
    /**
31
     * @var Node
32
     */
33
    protected $current;
34
35
    /**
36
     * @var Node|null
37
     */
38
    protected $next = null;
39
40
    /**
41
     * @var Node|null
42
     */
43
    protected $last = null;
44
45
    /**
46
     * @var ArrayCollection|null
47
     */
48
    protected $list = null;
49
50
    /**
51
     * @param Configuration $config
52
     */
53 27
    public function __construct(Configuration $config)
54
    {
55 27
        $this->config = $config;
56 27
    }
57
58
    /**
59
     * @return int
60
     */
61 14
    public function getTotal()
62
    {
63 14
        return $this->config->getTotalPages();
64
    }
65
66
    /**
67
     * @return Node|null
68
     */
69 5
    public function getFirst()
70
    {
71 5
        if (!$this->first && $this->config->getCurrentPage() > 1) {
72 4
            $this->first = new Node(1, $this->buildLink(1));
73
        }
74
75 5
        return $this->first;
76
    }
77
78
    /**
79
     * @return Node|null
80
     */
81 3
    public function getPrev()
82
    {
83 3
        if (!$this->prev && $this->config->getCurrentPage() > 1) {
84 2
            $this->prev = new Node(
85 2
                $this->config->getCurrentPage() - 1,
86 2
                $this->buildLink($this->config->getCurrentPage() - 1)
87
            );
88
        }
89
90 3
        return $this->prev;
91
    }
92
93
    /**
94
     * @return Node
95
     */
96 10
    public function getCurrent()
97
    {
98 10
        if (!$this->current) {
99 10
            $this->current = new Node(
100 10
                $this->config->getCurrentPage(),
101 10
                $this->buildLink($this->config->getCurrentPage()),
102 10
                true
103
            );
104
        }
105
106 10
        return $this->current;
107
    }
108
109
    /**
110
     * @return Node|null
111
     */
112 3
    public function getNext()
113
    {
114 3
        if (!$this->next && $this->config->getCurrentPage() < $this->getTotal()) {
115 2
            $this->next = new Node(
116 2
                $this->config->getCurrentPage() + 1,
117 2
                $this->buildLink($this->config->getCurrentPage() + 1)
118
            );
119
        }
120
121 3
        return $this->next;
122
    }
123
124
    /**
125
     * @return Node|null
126
     */
127 3
    public function getLast()
128
    {
129 3
        if (!$this->last && $this->config->getCurrentPage() < $this->getTotal()) {
130 2
            $this->last = new Node($this->getTotal(), $this->buildLink($this->getTotal()));
131
        }
132
133 3
        return $this->last;
134
    }
135
136
    /**
137
     * @return ArrayCollection|null
138
     */
139 7
    public function getIterator()
140
    {
141 7
        if (!($this->list instanceof ArrayCollection)) {
142 7
            $this->list = new ArrayCollection();
143
144 7
            if ($this->getTotal() <= 1) {
145 1
                return $this->list;
146
            }
147
148
            // definition of offset to the left and to the right of the selected page
149 6
            $left_offset = floor(($this->config->getMaxNavigate() - 1) / 2);
150 6
            $right_offset = ceil(($this->config->getMaxNavigate() - 1) / 2);
151
            // adjustment, if the offset is too large left
152 6
            if ($this->config->getCurrentPage() - $left_offset < 1) {
153 3
                $offset = abs($this->config->getCurrentPage() - 1 - $left_offset);
154 3
                $left_offset = $left_offset - $offset;
155 3
                $right_offset = $right_offset + $offset;
156
            }
157
            // adjustment, if the offset is too large right
158 6
            if ($this->config->getCurrentPage() + $right_offset > $this->getTotal()) {
159 3
                $offset = abs($this->getTotal() - $this->config->getCurrentPage() - $right_offset);
160 3
                $left_offset = $left_offset + $offset;
161 3
                $right_offset = $right_offset - $offset;
162
            }
163
            // determining the first and last pages in paging based on the current page and offset
164 6
            $page_from = $this->config->getCurrentPage() - $left_offset;
165 6
            $page_to = $this->config->getCurrentPage() + $right_offset;
166 6
            $page_from = $page_from > 1 ? $page_from : 1;
167
168
            // build list
169 6
            for ($page = $page_from; $page <= $page_to; ++$page) {
170 6
                if ($page == $this->config->getCurrentPage()) {
171 6
                    $this->list->add($this->getCurrent());
172
                } else {
173 6
                    $this->list->add(new Node($page, $this->buildLink($page)));
174
                }
175
            }
176
        }
177
178 6
        return $this->list;
179
    }
180
181
    /**
182
     * @param int $page
183
     *
184
     * @return string
185
     */
186 20
    protected function buildLink($page)
187
    {
188 20
        if ($page == 1 && $this->config->getFirstPageLink()) {
189 4
            return $this->config->getFirstPageLink();
190
        }
191
192 16
        if (is_callable($this->config->getPageLink())) {
193 6
            return call_user_func($this->config->getPageLink(), $page);
194
        } else {
195 10
            return sprintf($this->config->getPageLink(), $page);
196
        }
197
    }
198
}
199