Completed
Push — master ( 1c775c...37f823 )
by Peter
05:37
created

View::buildLink()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 4.074

Importance

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